diff options
author | Richard Ash <richard@audacityteam.org> | 2009-08-20 06:24:49 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-15 15:01:36 -0400 |
commit | d3f0e10a702defea05b6c3277ec6326c87138e82 (patch) | |
tree | a6812961c9b011ea20a2e4f0f80d96e895b534a8 | |
parent | 2715dd6a93c69b29f59bec4c6e2fca84883078f0 (diff) |
Staging: quatech_usb2: vendor implementation of break_ctl
This patch imports the implementation of the break_ctl, throttle and
unthrottle methods from the vendor driver into the staging driver. This
compiles but is not yet tested.
Signed-off-by: Richard Ash <richard@audacityteam.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/staging/quatech_usb2/quatech_usb2.c | 220 |
1 files changed, 180 insertions, 40 deletions
diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c index f71921998ce..b06e90d3cef 100644 --- a/drivers/staging/quatech_usb2/quatech_usb2.c +++ b/drivers/staging/quatech_usb2/quatech_usb2.c | |||
@@ -56,11 +56,11 @@ static int debug; | |||
56 | #define QT2_GET_SET_UART 0xc1 | 56 | #define QT2_GET_SET_UART 0xc1 |
57 | #define QT2_HW_FLOW_CONTROL_MASK 0xc5 | 57 | #define QT2_HW_FLOW_CONTROL_MASK 0xc5 |
58 | #define QT2_SW_FLOW_CONTROL_MASK 0xc6 | 58 | #define QT2_SW_FLOW_CONTROL_MASK 0xc6 |
59 | #define QT2_SW_FLOW_CONTROL_DISABLE 0xc7 | 59 | #define QT2_SW_FLOW_CONTROL_DISABLE 0xc7 |
60 | /*#define QT_BREAK_CONTROL 0xc8 | 60 | #define QT2_BREAK_CONTROL 0xc8 |
61 | #define QT_STOP_RECEIVE 0xe0*/ | 61 | #define QT2_STOP_RECEIVE 0xe0 |
62 | #define QT2_FLUSH_DEVICE 0xc4 | 62 | #define QT2_FLUSH_DEVICE 0xc4 |
63 | #define QT_GET_SET_QMCR 0xe1 | 63 | #define QT2_GET_SET_QMCR 0xe1 |
64 | 64 | ||
65 | /* sorts of flush we can do on */ | 65 | /* sorts of flush we can do on */ |
66 | #define QT2_FLUSH_RX 0x00 | 66 | #define QT2_FLUSH_RX 0x00 |
@@ -138,31 +138,21 @@ static struct usb_driver quausb2_usb_driver = { | |||
138 | .no_dynamic_id = 1, | 138 | .no_dynamic_id = 1, |
139 | }; | 139 | }; |
140 | 140 | ||
141 | /** structure in which to keep all the messy stuff that this driver needs | 141 | /** |
142 | * alongside the usb_serial_port structure | 142 | * quatech2_port: Structure in which to keep all the messy stuff that this |
143 | * @param read_urb_busy Flag indicating that port->read_urb is in use | 143 | * driver needs alongside the usb_serial_port structure |
144 | * @param close_pending flag indicating that this port is in the process of | 144 | * @read_urb_busy: Flag indicating that port->read_urb is in use |
145 | * @close_pending: flag indicating that this port is in the process of | ||
145 | * being closed (and so no new reads / writes should be started). | 146 | * being closed (and so no new reads / writes should be started). |
146 | * @param shadowLSR Last received state of the line status register, holds the | 147 | * @shadowLSR: Last received state of the line status register, holds the |
147 | * value of the line status flags from the port | 148 | * value of the line status flags from the port |
148 | * @param shadowMSR Last received state of the modem status register, holds | 149 | * @shadowMSR: Last received state of the modem status register, holds |
149 | * the value of the modem status received from the port | 150 | * the value of the modem status received from the port |
150 | * @param rcv_flush Flag indicating that a receive flush has occured on | 151 | * @rcv_flush: Flag indicating that a receive flush has occured on |
151 | * the hardware. | 152 | * the hardware. |
152 | * @param xmit_flush Flag indicating that a transmit flush has been processed by | 153 | * @xmit_flush: Flag indicating that a transmit flush has been processed by |
153 | * the hardware. | 154 | * the hardware. |
154 | * @param fifo_empty_flag | 155 | * @tx_pending_bytes: Number of bytes waiting to be sent. This total |
155 | * - Starts off true when port opened | ||
156 | * - set false when a write is submitted to the driver | ||
157 | * - as far as I can see not true again until device is re-opened. | ||
158 | * - read in a number of places. | ||
159 | * @param tx_fifo_room | ||
160 | * - set to FIFO_DEPTH when port opened | ||
161 | * - decremented by tc_pending_bytes when a new write is submitted. | ||
162 | * - set to FIFO_DEPTH when "xmit_empty" is received from the device, | ||
163 | * regardless of how many bytes were reported to have been sent (?) | ||
164 | * | ||
165 | * @param tx_pending_bytes Number of bytes waiting to be sent. This total | ||
166 | * includes the size (excluding header) of URBs that have been submitted but | 156 | * includes the size (excluding header) of URBs that have been submitted but |
167 | * have not yet been sent to to the device, and bytes that have been sent out | 157 | * have not yet been sent to to the device, and bytes that have been sent out |
168 | * of the port but not yet reported sent by the "xmit_empty" messages (which | 158 | * of the port but not yet reported sent by the "xmit_empty" messages (which |
@@ -173,6 +163,10 @@ static struct usb_driver quausb2_usb_driver = { | |||
173 | * each time a write urb is dispatched. | 163 | * each time a write urb is dispatched. |
174 | * - is decremented each time a "transmit empty" message is received | 164 | * - is decremented each time a "transmit empty" message is received |
175 | * by the driver in the data stream. | 165 | * by the driver in the data stream. |
166 | * @sem: Semaphore to lock access to this structure when we need to ensure that | ||
167 | * races don't occur to access bits of it. | ||
168 | * @open_count: The number of uses of the port currently having | ||
169 | * it open, i.e. the reference count. | ||
176 | */ | 170 | */ |
177 | struct quatech2_port { | 171 | struct quatech2_port { |
178 | int magic; | 172 | int magic; |
@@ -180,18 +174,16 @@ struct quatech2_port { | |||
180 | bool close_pending; | 174 | bool close_pending; |
181 | __u8 shadowLSR; | 175 | __u8 shadowLSR; |
182 | __u8 shadowMSR; | 176 | __u8 shadowMSR; |
183 | /*int xmit_fifo_room_bytes;*/ | ||
184 | bool rcv_flush; | 177 | bool rcv_flush; |
185 | bool xmit_flush; | 178 | bool xmit_flush; |
186 | /* bool fifo_empty_flag; | ||
187 | int tx_fifo_room;*/ | ||
188 | int tx_pending_bytes; | 179 | int tx_pending_bytes; |
180 | struct semaphore sem; | ||
181 | int open_count; | ||
189 | 182 | ||
190 | char active; /* someone has this device open */ | 183 | char active; /* someone has this device open */ |
191 | unsigned char *xfer_to_tty_buffer; | 184 | unsigned char *xfer_to_tty_buffer; |
192 | wait_queue_head_t wait; | 185 | wait_queue_head_t wait; |
193 | int open_count; /* number of times this port has been opened */ | 186 | |
194 | struct semaphore sem; /* locks this structure */ | ||
195 | __u8 shadowLCR; /* last LCR value received */ | 187 | __u8 shadowLCR; /* last LCR value received */ |
196 | __u8 shadowMCR; /* last MCR value received */ | 188 | __u8 shadowMCR; /* last MCR value received */ |
197 | char RxHolding; | 189 | char RxHolding; |
@@ -281,6 +273,8 @@ static int qt2_boxsethw_flowctl(struct usb_serial *serial, | |||
281 | static int qt2_boxsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber, | 273 | static int qt2_boxsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber, |
282 | unsigned char stop_char, unsigned char start_char); | 274 | unsigned char stop_char, unsigned char start_char); |
283 | static int qt2_boxunsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber); | 275 | static int qt2_boxunsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber); |
276 | static int qt2_boxstoprx(struct usb_serial *serial, unsigned short uart_number, | ||
277 | unsigned short stop); | ||
284 | 278 | ||
285 | /* implementation functions, roughly in order of use, are here */ | 279 | /* implementation functions, roughly in order of use, are here */ |
286 | static int qt2_calc_num_ports(struct usb_serial *serial) | 280 | static int qt2_calc_num_ports(struct usb_serial *serial) |
@@ -359,6 +353,8 @@ static int qt2_attach(struct usb_serial *serial) | |||
359 | __func__, i); | 353 | __func__, i); |
360 | return -ENOMEM; | 354 | return -ENOMEM; |
361 | } | 355 | } |
356 | /* initialise stuff in the structure */ | ||
357 | qt2_port->open_count = 0; /* port is not open */ | ||
362 | spin_lock_init(&qt2_port->lock); | 358 | spin_lock_init(&qt2_port->lock); |
363 | qt2_set_port_private(port, qt2_port); | 359 | qt2_set_port_private(port, qt2_port); |
364 | } | 360 | } |
@@ -577,8 +573,6 @@ int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
577 | port->bulk_out_size, | 573 | port->bulk_out_size, |
578 | qt2_write_bulk_callback, | 574 | qt2_write_bulk_callback, |
579 | port); | 575 | port); |
580 | /*port_extra->fifo_empty_flag = true; | ||
581 | port_extra->tx_fifo_room = FIFO_DEPTH;*/ | ||
582 | port_extra->tx_pending_bytes = 0; | 576 | port_extra->tx_pending_bytes = 0; |
583 | 577 | ||
584 | if (dev_extra->open_ports == 0) { | 578 | if (dev_extra->open_ports == 0) { |
@@ -615,6 +609,8 @@ int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
615 | 609 | ||
616 | /* initialize our wait queues */ | 610 | /* initialize our wait queues */ |
617 | init_waitqueue_head(&port_extra->wait); | 611 | init_waitqueue_head(&port_extra->wait); |
612 | /* increment the count of openings of this port by one */ | ||
613 | port_extra->open_count++; | ||
618 | 614 | ||
619 | /* remember to store dev_extra, port_extra and port0_extra back again at | 615 | /* remember to store dev_extra, port_extra and port0_extra back again at |
620 | * end !*/ | 616 | * end !*/ |
@@ -696,6 +692,9 @@ static void qt2_close(struct usb_serial_port *port) | |||
696 | port->bulk_out_buffer = NULL; | 692 | port->bulk_out_buffer = NULL; |
697 | port->bulk_out_size = 0; | 693 | port->bulk_out_size = 0; |
698 | 694 | ||
695 | /* decrement the count of openings of this port by one */ | ||
696 | port_extra->open_count--; | ||
697 | /* one less overall open as well */ | ||
699 | dev_extra->open_ports--; | 698 | dev_extra->open_ports--; |
700 | dbg("%s(): Exit, dev_extra->open_ports = %d", __func__, | 699 | dbg("%s(): Exit, dev_extra->open_ports = %d", __func__, |
701 | dev_extra->open_ports); | 700 | dev_extra->open_ports); |
@@ -1027,7 +1026,7 @@ static void qt2_set_termios(struct tty_struct *tty, | |||
1027 | /* Round to nearest divisor */ | 1026 | /* Round to nearest divisor */ |
1028 | if (((remainder * 2) >= baud) && (baud != 110)) | 1027 | if (((remainder * 2) >= baud) && (baud != 110)) |
1029 | divisor++; | 1028 | divisor++; |
1030 | dbg("%s(): setting divisor = %d, QT2_MAX_BAUD_RATE = %d , LCR = 0x%x", | 1029 | dbg("%s(): setting divisor = %d, QT2_MAX_BAUD_RATE = %d , LCR = %#.2x", |
1031 | __func__, divisor, QT2_MAX_BAUD_RATE, LCR_change_to); | 1030 | __func__, divisor, QT2_MAX_BAUD_RATE, LCR_change_to); |
1032 | 1031 | ||
1033 | status = qt2_boxsetuart(serial, UartNumber, (unsigned short) divisor, | 1032 | status = qt2_boxsetuart(serial, UartNumber, (unsigned short) divisor, |
@@ -1156,6 +1155,131 @@ static int qt2_tiocmset(struct tty_struct *tty, struct file *file, | |||
1156 | return 0; | 1155 | return 0; |
1157 | } | 1156 | } |
1158 | 1157 | ||
1158 | /** qt2_break - Turn BREAK on and off on the UARTs | ||
1159 | */ | ||
1160 | static void qt2_break(struct tty_struct *tty, int break_state) | ||
1161 | { | ||
1162 | struct usb_serial_port *port = tty->driver_data; /* parent port */ | ||
1163 | struct usb_serial *serial = port->serial; /* parent device */ | ||
1164 | struct quatech2_port *port_extra; /* extra data for this port */ | ||
1165 | __u16 break_value; | ||
1166 | unsigned int result; | ||
1167 | |||
1168 | port_extra = qt2_get_port_private(port); | ||
1169 | if (!serial) { | ||
1170 | dbg("%s(): port %d: no serial object", __func__, port->number); | ||
1171 | return; | ||
1172 | } | ||
1173 | |||
1174 | if (break_state == -1) | ||
1175 | break_value = 1; | ||
1176 | else | ||
1177 | break_value = 0; | ||
1178 | dbg("%s(): port %d, break_value %d", __func__, port->number, | ||
1179 | break_value); | ||
1180 | |||
1181 | down(&port_extra->sem); | ||
1182 | if (!port_extra->open_count) { | ||
1183 | dbg("%s(): port not open", __func__); | ||
1184 | goto exit; | ||
1185 | } | ||
1186 | |||
1187 | result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | ||
1188 | QT2_BREAK_CONTROL, 0x40, break_value, | ||
1189 | port->number, NULL, 0, 300); | ||
1190 | exit: | ||
1191 | up(&port_extra->sem); | ||
1192 | dbg("%s(): exit port %d", __func__, port->number); | ||
1193 | |||
1194 | } | ||
1195 | /** | ||
1196 | * qt2_throttle: - stop reading new data from the port | ||
1197 | */ | ||
1198 | static void qt2_throttle(struct tty_struct *tty) | ||
1199 | { | ||
1200 | struct usb_serial_port *port = tty->driver_data; | ||
1201 | struct usb_serial *serial = port->serial; | ||
1202 | struct quatech2_port *port_extra; /* extra data for this port */ | ||
1203 | dbg("%s(): port %d", __func__, port->number); | ||
1204 | |||
1205 | port_extra = qt2_get_port_private(port); | ||
1206 | if (!serial) { | ||
1207 | dbg("%s(): enter port %d no serial object", __func__, | ||
1208 | port->number); | ||
1209 | return; | ||
1210 | } | ||
1211 | |||
1212 | down(&port_extra->sem); /* lock structure */ | ||
1213 | if (!port_extra->open_count) { | ||
1214 | dbg("%s(): port not open", __func__); | ||
1215 | goto exit; | ||
1216 | } | ||
1217 | /* Send command to box to stop receiving stuff. This will stop this | ||
1218 | * particular UART from filling the endpoint - in the multiport case the | ||
1219 | * FPGA UART will handle any flow control implmented, but for the single | ||
1220 | * port it's handed differently and we just quit submitting urbs | ||
1221 | */ | ||
1222 | if (serial->dev->descriptor.idProduct != QUATECH_SSU2_100) | ||
1223 | qt2_boxstoprx(serial, port->number, 1); | ||
1224 | |||
1225 | port->throttled = 1; | ||
1226 | exit: | ||
1227 | up(&port_extra->sem); | ||
1228 | dbg("%s(): port %d: setting port->throttled", __func__, port->number); | ||
1229 | return; | ||
1230 | } | ||
1231 | |||
1232 | /** | ||
1233 | * qt2_unthrottle: - start receiving data through the port again after being | ||
1234 | * throttled | ||
1235 | */ | ||
1236 | static void qt2_unthrottle(struct tty_struct *tty) | ||
1237 | { | ||
1238 | struct usb_serial_port *port = tty->driver_data; | ||
1239 | struct usb_serial *serial = port->serial; | ||
1240 | struct quatech2_port *port_extra; /* extra data for this port */ | ||
1241 | struct usb_serial_port *port0; /* first port structure on device */ | ||
1242 | struct quatech2_dev *dev_extra; /* extra data for the device */ | ||
1243 | |||
1244 | if (!serial) { | ||
1245 | dbg("%s() enter port %d no serial object!", __func__, | ||
1246 | port->number); | ||
1247 | return; | ||
1248 | } | ||
1249 | dbg("%s(): enter port %d", __func__, port->number); | ||
1250 | dev_extra = qt2_get_dev_private(serial); | ||
1251 | port_extra = qt2_get_port_private(port); | ||
1252 | port0 = serial->port[0]; /* get the first port's device structure */ | ||
1253 | |||
1254 | down(&port_extra->sem); | ||
1255 | if (!port_extra->open_count) { | ||
1256 | dbg("%s(): port %d not open", __func__, port->number); | ||
1257 | goto exit; | ||
1258 | } | ||
1259 | |||
1260 | if (port->throttled != 0) { | ||
1261 | dbg("%s(): port %d: unsetting port->throttled", __func__, | ||
1262 | port->number); | ||
1263 | port->throttled = 0; | ||
1264 | /* Send command to box to start receiving stuff */ | ||
1265 | if (serial->dev->descriptor.idProduct != QUATECH_SSU2_100) { | ||
1266 | qt2_boxstoprx(serial, port->number, 0); | ||
1267 | } else if (dev_extra->ReadBulkStopped == true) { | ||
1268 | usb_fill_bulk_urb(port0->read_urb, serial->dev, | ||
1269 | usb_rcvbulkpipe(serial->dev, | ||
1270 | port0->bulk_in_endpointAddress), | ||
1271 | port0->bulk_in_buffer, | ||
1272 | port0->bulk_in_size, | ||
1273 | qt2_read_bulk_callback, | ||
1274 | serial); | ||
1275 | } | ||
1276 | } | ||
1277 | exit: | ||
1278 | up(&port_extra->sem); | ||
1279 | dbg("%s(): exit port %d", __func__, port->number); | ||
1280 | return; | ||
1281 | } | ||
1282 | |||
1159 | /* internal, private helper functions for the driver */ | 1283 | /* internal, private helper functions for the driver */ |
1160 | 1284 | ||
1161 | /* Power up the FPGA in the box to get it working */ | 1285 | /* Power up the FPGA in the box to get it working */ |
@@ -1173,7 +1297,7 @@ static int qt2_boxpoweron(struct usb_serial *serial) | |||
1173 | } | 1297 | } |
1174 | 1298 | ||
1175 | /* | 1299 | /* |
1176 | * qt2_boxsetQMCR Issue a QT_GET_SET_QMCR vendor-spcific request on the | 1300 | * qt2_boxsetQMCR Issue a QT2_GET_SET_QMCR vendor-spcific request on the |
1177 | * default control pipe. If successful return the number of bytes written, | 1301 | * default control pipe. If successful return the number of bytes written, |
1178 | * otherwise return a negative error number of the problem. | 1302 | * otherwise return a negative error number of the problem. |
1179 | */ | 1303 | */ |
@@ -1189,7 +1313,7 @@ static int qt2_boxsetQMCR(struct usb_serial *serial, __u16 Uart_Number, | |||
1189 | Uart_Number, PortSettings); | 1313 | Uart_Number, PortSettings); |
1190 | 1314 | ||
1191 | result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | 1315 | result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
1192 | QT_GET_SET_QMCR, 0x40, PortSettings, | 1316 | QT2_GET_SET_QMCR, 0x40, PortSettings, |
1193 | (__u16)Uart_Number, NULL, 0, 5000); | 1317 | (__u16)Uart_Number, NULL, 0, 5000); |
1194 | return result; | 1318 | return result; |
1195 | } | 1319 | } |
@@ -1388,7 +1512,7 @@ __func__); | |||
1388 | 1512 | ||
1389 | /* active is a usb_serial_port. It has a member port which is a | 1513 | /* active is a usb_serial_port. It has a member port which is a |
1390 | * tty_port. From this we get a tty_struct pointer which is what we | 1514 | * tty_port. From this we get a tty_struct pointer which is what we |
1391 | * actually wanted, and keep it on tty_st */ | 1515 | * actually wanted, and keep it on tty_st */ |
1392 | tty_st = tty_port_tty_get(&active->port); | 1516 | tty_st = tty_port_tty_get(&active->port); |
1393 | if (!tty_st) { | 1517 | if (!tty_st) { |
1394 | dbg("%s - bad tty pointer - exiting", __func__); | 1518 | dbg("%s - bad tty pointer - exiting", __func__); |
@@ -1457,7 +1581,7 @@ __func__); | |||
1457 | } | 1581 | } |
1458 | /* Port change. If port open push | 1582 | /* Port change. If port open push |
1459 | * current data up to tty layer */ | 1583 | * current data up to tty layer */ |
1460 | if (dev_extra->open_ports > 0) | 1584 | if (active_extra->open_count > 0) |
1461 | tty_flip_buffer_push(tty_st); | 1585 | tty_flip_buffer_push(tty_st); |
1462 | 1586 | ||
1463 | dbg("Port Change: new port = %d", | 1587 | dbg("Port Change: new port = %d", |
@@ -1798,6 +1922,22 @@ static int qt2_boxunsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber) | |||
1798 | 0, 300); | 1922 | 0, 300); |
1799 | } | 1923 | } |
1800 | 1924 | ||
1925 | /** | ||
1926 | * qt2_boxstoprx - Start and stop reception of data by the FPGA UART in | ||
1927 | * response to requests from the tty layer | ||
1928 | * @serial: pointer to the usb_serial structure for the parent device | ||
1929 | * @uart_number: which UART on the device we are addressing | ||
1930 | * @stop: Whether to start or stop data reception. Set to 1 to stop data being | ||
1931 | * received, and to 0 to start it being received. | ||
1932 | */ | ||
1933 | static int qt2_boxstoprx(struct usb_serial *serial, unsigned short uart_number, | ||
1934 | unsigned short stop) | ||
1935 | { | ||
1936 | return usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | ||
1937 | QT2_STOP_RECEIVE, 0x40, stop, uart_number, NULL, 0, 300); | ||
1938 | } | ||
1939 | |||
1940 | |||
1801 | /* | 1941 | /* |
1802 | * last things in file: stuff to register this driver into the generic | 1942 | * last things in file: stuff to register this driver into the generic |
1803 | * USB serial framework. | 1943 | * USB serial framework. |
@@ -1817,12 +1957,12 @@ static struct usb_serial_driver quatech2_device = { | |||
1817 | .write = qt2_write, | 1957 | .write = qt2_write, |
1818 | .write_room = qt2_write_room, | 1958 | .write_room = qt2_write_room, |
1819 | .chars_in_buffer = qt2_chars_in_buffer, | 1959 | .chars_in_buffer = qt2_chars_in_buffer, |
1820 | /*.throttle = qt_throttle, | 1960 | .throttle = qt2_throttle, |
1821 | .unthrottle = qt_unthrottle,*/ | 1961 | .unthrottle = qt2_unthrottle, |
1822 | .calc_num_ports = qt2_calc_num_ports, | 1962 | .calc_num_ports = qt2_calc_num_ports, |
1823 | .ioctl = qt2_ioctl, | 1963 | .ioctl = qt2_ioctl, |
1824 | .set_termios = qt2_set_termios, | 1964 | .set_termios = qt2_set_termios, |
1825 | /*.break_ctl = qt_break,*/ | 1965 | .break_ctl = qt2_break, |
1826 | .tiocmget = qt2_tiocmget, | 1966 | .tiocmget = qt2_tiocmget, |
1827 | .tiocmset = qt2_tiocmset, | 1967 | .tiocmset = qt2_tiocmset, |
1828 | .attach = qt2_attach, | 1968 | .attach = qt2_attach, |