Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /************************************************************************ |
2 | * | |
3 | * IONSP.H Definitions for I/O Networks Serial Protocol | |
4 | * | |
5 | * Copyright (C) 1997-1998 Inside Out Networks, Inc. | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * These definitions are used by both kernel-mode driver and the | |
13 | * peripheral firmware and MUST be kept in sync. | |
14 | * | |
15 | ************************************************************************/ | |
16 | ||
17 | /************************************************************************ | |
18 | ||
19 | The data to and from all ports on the peripheral is multiplexed | |
20 | through a single endpoint pair (EP1 since it supports 64-byte | |
21 | MaxPacketSize). Therefore, the data, commands, and status for | |
22 | each port must be preceded by a short header identifying the | |
23 | destination port. The header also identifies the bytes that follow | |
24 | as data or as command/status info. | |
25 | ||
26 | Header format, first byte: | |
27 | ||
28 | CLLLLPPP | |
29 | -------- | |
30 | | | |------ Port Number: 0-7 | |
31 | | |--------- Length: MSB bits of length | |
32 | |----------- Data/Command: 0 = Data header | |
33 | 1 = Cmd / Status (Cmd if OUT, Status if IN) | |
34 | ||
35 | This gives 2 possible formats: | |
36 | ||
37 | ||
38 | Data header: 0LLLLPPP LLLLLLLL | |
39 | ============ | |
40 | ||
41 | Where (LLLL,LLLLLLL) is 12-bit length of data that follows for | |
42 | port number (PPP). The length is 0-based (0-FFF means 0-4095 | |
43 | bytes). The ~4K limit allows the host driver (which deals in | |
44 | transfer requests instead of individual packets) to write a | |
45 | large chunk of data in a single request. Note, however, that | |
46 | the length must always be <= the current TxCredits for a given | |
47 | port due to buffering limitations on the peripheral. | |
48 | ||
49 | ||
50 | Cmd/Status header: 1ccccPPP [ CCCCCCCC, Params ]... | |
51 | ================== | |
52 | ||
53 | Where (cccc) or (cccc,CCCCCCCC) is the cmd or status identifier. | |
54 | Frequently-used values are encoded as (cccc), longer ones using | |
55 | (cccc,CCCCCCCC). Subsequent bytes are optional parameters and are | |
56 | specific to the cmd or status code. This may include a length | |
57 | for command and status codes that need variable-length parameters. | |
58 | ||
59 | ||
60 | In addition, we use another interrupt pipe (endpoint) which the host polls | |
61 | periodically for flow control information. The peripheral, when there has | |
62 | been a change, sends the following 10-byte packet: | |
63 | ||
64 | RRRRRRRRRRRRRRRR | |
65 | T0T0T0T0T0T0T0T0 | |
66 | T1T1T1T1T1T1T1T1 | |
67 | T2T2T2T2T2T2T2T2 | |
68 | T3T3T3T3T3T3T3T3 | |
69 | ||
70 | The first field is the 16-bit RxBytesAvail field, which indicates the | |
71 | number of bytes which may be read by the host from EP1. This is necessary: | |
72 | (a) because OSR2.1 has a bug which causes data loss if the peripheral returns | |
73 | fewer bytes than the host expects to read, and (b) because, on Microsoft | |
74 | platforms at least, an outstanding read posted on EP1 consumes about 35% of | |
75 | the CPU just polling the device for data. | |
76 | ||
77 | The next 4 fields are the 16-bit TxCredits for each port, which indicate how | |
78 | many bytes the host is allowed to send on EP1 for transmit to a given port. | |
79 | After an OPEN_PORT command, the Edgeport sends the initial TxCredits for that | |
80 | port. | |
81 | ||
82 | All 16-bit fields are sent in little-endian (Intel) format. | |
83 | ||
84 | ************************************************************************/ | |
85 | ||
86 | // | |
87 | // Define format of InterruptStatus packet returned from the | |
88 | // Interrupt pipe | |
89 | // | |
90 | ||
91 | struct int_status_pkt { | |
a3204711 GKH |
92 | __u16 RxBytesAvail; // Additional bytes available to |
93 | // be read from Bulk IN pipe | |
94 | __u16 TxCredits[MAX_RS232_PORTS]; // Additional space available in | |
95 | // given port's TxBuffer | |
1da177e4 LT |
96 | }; |
97 | ||
98 | ||
99 | #define GET_INT_STATUS_SIZE(NumPorts) (sizeof(__u16) + (sizeof(__u16) * (NumPorts))) | |
100 | ||
101 | ||
102 | ||
103 | // | |
104 | // Define cmd/status header values and macros to extract them. | |
105 | // | |
106 | // Data: 0LLLLPPP LLLLLLLL | |
107 | // Cmd/Stat: 1ccccPPP CCCCCCCC | |
108 | ||
109 | #define IOSP_DATA_HDR_SIZE 2 | |
110 | #define IOSP_CMD_HDR_SIZE 2 | |
111 | ||
112 | #define IOSP_MAX_DATA_LENGTH 0x0FFF // 12 bits -> 4K | |
113 | ||
114 | #define IOSP_PORT_MASK 0x07 // Mask to isolate port number | |
115 | #define IOSP_CMD_STAT_BIT 0x80 // If set, this is command/status header | |
116 | ||
117 | #define IS_CMD_STAT_HDR(Byte1) ((Byte1) & IOSP_CMD_STAT_BIT) | |
a3204711 | 118 | #define IS_DATA_HDR(Byte1) (!IS_CMD_STAT_HDR(Byte1)) |
1da177e4 LT |
119 | |
120 | #define IOSP_GET_HDR_PORT(Byte1) ((__u8) ((Byte1) & IOSP_PORT_MASK)) | |
a3204711 | 121 | #define IOSP_GET_HDR_DATA_LEN(Byte1, Byte2) ((__u16) (((__u16)((Byte1) & 0x78)) << 5) | (Byte2)) |
1da177e4 LT |
122 | #define IOSP_GET_STATUS_CODE(Byte1) ((__u8) (((Byte1) & 0x78) >> 3)) |
123 | ||
124 | ||
125 | // | |
126 | // These macros build the 1st and 2nd bytes for a data header | |
127 | // | |
a3204711 | 128 | #define IOSP_BUILD_DATA_HDR1(Port, Len) ((__u8) (((Port) | ((__u8) (((__u16) (Len)) >> 5) & 0x78)))) |
1da177e4 LT |
129 | #define IOSP_BUILD_DATA_HDR2(Port, Len) ((__u8) (Len)) |
130 | ||
131 | ||
132 | // | |
133 | // These macros build the 1st and 2nd bytes for a command header | |
134 | // | |
a3204711 | 135 | #define IOSP_BUILD_CMD_HDR1(Port, Cmd) ((__u8) (IOSP_CMD_STAT_BIT | (Port) | ((__u8) ((Cmd) << 3)))) |
1da177e4 LT |
136 | |
137 | ||
138 | //-------------------------------------------------------------- | |
139 | // | |
140 | // Define values for commands and command parameters | |
141 | // (sent from Host to Edgeport) | |
142 | // | |
143 | // 1ccccPPP P1P1P1P1 [ P2P2P2P2P2 ]... | |
144 | // | |
145 | // cccc: 00-07 2-byte commands. Write UART register 0-7 with | |
146 | // value in P1. See 16650.H for definitions of | |
147 | // UART register numbers and contents. | |
148 | // | |
149 | // 08-0B 3-byte commands: ==== P1 ==== ==== P2 ==== | |
150 | // 08 available for expansion | |
151 | // 09 1-param commands Command Code Param | |
152 | // 0A available for expansion | |
153 | // 0B available for expansion | |
154 | // | |
155 | // 0C-0D 4-byte commands. P1 = extended cmd and P2,P3 = params | |
156 | // Currently unimplemented. | |
157 | // | |
158 | // 0E-0F N-byte commands: P1 = num bytes after P1 (ie, TotalLen - 2) | |
159 | // P2 = extended cmd, P3..Pn = parameters. | |
160 | // Currently unimplemented. | |
161 | // | |
162 | ||
163 | #define IOSP_WRITE_UART_REG(n) ((n) & 0x07) // UartReg[ n ] := P1 | |
164 | ||
165 | // Register numbers and contents | |
166 | // defined in 16554.H. | |
167 | ||
168 | // 0x08 // Available for expansion. | |
169 | #define IOSP_EXT_CMD 0x09 // P1 = Command code (defined below) | |
170 | ||
171 | // P2 = Parameter | |
172 | ||
173 | // | |
174 | // Extended Command values, used with IOSP_EXT_CMD, may | |
175 | // or may not use parameter P2. | |
176 | // | |
177 | ||
178 | #define IOSP_CMD_OPEN_PORT 0x00 // Enable ints, init UART. (NO PARAM) | |
179 | #define IOSP_CMD_CLOSE_PORT 0x01 // Disable ints, flush buffers. (NO PARAM) | |
180 | #define IOSP_CMD_CHASE_PORT 0x02 // Wait for Edgeport TX buffers to empty. (NO PARAM) | |
181 | #define IOSP_CMD_SET_RX_FLOW 0x03 // Set Rx Flow Control in Edgeport | |
182 | #define IOSP_CMD_SET_TX_FLOW 0x04 // Set Tx Flow Control in Edgeport | |
183 | #define IOSP_CMD_SET_XON_CHAR 0x05 // Set XON Character in Edgeport | |
184 | #define IOSP_CMD_SET_XOFF_CHAR 0x06 // Set XOFF Character in Edgeport | |
185 | #define IOSP_CMD_RX_CHECK_REQ 0x07 // Request Edgeport to insert a Checkpoint into | |
186 | ||
187 | // the receive data stream (Parameter = 1 byte sequence number) | |
188 | ||
189 | #define IOSP_CMD_SET_BREAK 0x08 // Turn on the BREAK (LCR bit 6) | |
190 | #define IOSP_CMD_CLEAR_BREAK 0x09 // Turn off the BREAK (LCR bit 6) | |
191 | ||
192 | ||
193 | // | |
194 | // Define macros to simplify building of IOSP cmds | |
195 | // | |
196 | ||
a3204711 GKH |
197 | #define MAKE_CMD_WRITE_REG(ppBuf, pLen, Port, Reg, Val) \ |
198 | do { \ | |
199 | (*(ppBuf))[0] = IOSP_BUILD_CMD_HDR1((Port), \ | |
200 | IOSP_WRITE_UART_REG(Reg)); \ | |
201 | (*(ppBuf))[1] = (Val); \ | |
202 | \ | |
203 | *ppBuf += 2; \ | |
204 | *pLen += 2; \ | |
205 | } while (0) | |
1da177e4 | 206 | |
a3204711 GKH |
207 | #define MAKE_CMD_EXT_CMD(ppBuf, pLen, Port, ExtCmd, Param) \ |
208 | do { \ | |
209 | (*(ppBuf))[0] = IOSP_BUILD_CMD_HDR1((Port), IOSP_EXT_CMD); \ | |
210 | (*(ppBuf))[1] = (ExtCmd); \ | |
211 | (*(ppBuf))[2] = (Param); \ | |
212 | \ | |
213 | *ppBuf += 3; \ | |
214 | *pLen += 3; \ | |
215 | } while (0) | |
1da177e4 LT |
216 | |
217 | ||
218 | ||
219 | //-------------------------------------------------------------- | |
220 | // | |
221 | // Define format of flow control commands | |
222 | // (sent from Host to Edgeport) | |
223 | // | |
224 | // 11001PPP FlowCmd FlowTypes | |
225 | // | |
226 | // Note that the 'FlowTypes' parameter is a bit mask; that is, | |
227 | // more than one flow control type can be active at the same time. | |
228 | // FlowTypes = 0 means 'no flow control'. | |
229 | // | |
230 | ||
231 | // | |
232 | // IOSP_CMD_SET_RX_FLOW | |
233 | // | |
234 | // Tells Edgeport how it can stop incoming UART data | |
235 | // | |
236 | // Example for Port 0 | |
237 | // P0 = 11001000 | |
238 | // P1 = IOSP_CMD_SET_RX_FLOW | |
239 | // P2 = Bit mask as follows: | |
240 | ||
241 | #define IOSP_RX_FLOW_RTS 0x01 // Edgeport drops RTS to stop incoming data | |
242 | #define IOSP_RX_FLOW_DTR 0x02 // Edgeport drops DTR to stop incoming data | |
243 | #define IOSP_RX_FLOW_DSR_SENSITIVITY 0x04 // Ignores Rx data unless DSR high | |
244 | ||
245 | // Not currently implemented by firmware. | |
246 | #define IOSP_RX_FLOW_XON_XOFF 0x08 // Edgeport sends XOFF char to stop incoming data. | |
247 | ||
248 | // Host must have previously programmed the | |
249 | // XON/XOFF values with SET_XON/SET_XOFF | |
250 | // before enabling this bit. | |
251 | ||
252 | // | |
253 | // IOSP_CMD_SET_TX_FLOW | |
254 | // | |
255 | // Tells Edgeport what signal(s) will stop it from transmitting UART data | |
256 | // | |
257 | // Example for Port 0 | |
258 | // P0 = 11001000 | |
259 | // P1 = IOSP_CMD_SET_TX_FLOW | |
260 | // P2 = Bit mask as follows: | |
261 | ||
262 | #define IOSP_TX_FLOW_CTS 0x01 // Edgeport stops Tx if CTS low | |
263 | #define IOSP_TX_FLOW_DSR 0x02 // Edgeport stops Tx if DSR low | |
264 | #define IOSP_TX_FLOW_DCD 0x04 // Edgeport stops Tx if DCD low | |
265 | #define IOSP_TX_FLOW_XON_XOFF 0x08 // Edgeport stops Tx upon receiving XOFF char. | |
266 | ||
267 | // Host must have previously programmed the | |
268 | // XON/XOFF values with SET_XON/SET_XOFF | |
269 | // before enabling this bit. | |
270 | #define IOSP_TX_FLOW_XOFF_CONTINUE 0x10 // If not set, Edgeport stops Tx when | |
271 | ||
272 | // sending XOFF in order to fix broken | |
273 | // systems that interpret the next | |
274 | // received char as XON. | |
275 | // If set, Edgeport continues Tx | |
276 | // normally after transmitting XOFF. | |
277 | // Not currently implemented by firmware. | |
278 | #define IOSP_TX_TOGGLE_RTS 0x20 // Edgeport drives RTS as a true half-duplex | |
279 | ||
280 | // Request-to-Send signal: it is raised before | |
281 | // beginning transmission and lowered after | |
282 | // the last Tx char leaves the UART. | |
283 | // Not currently implemented by firmware. | |
284 | ||
285 | // | |
286 | // IOSP_CMD_SET_XON_CHAR | |
287 | // | |
288 | // Sets the character which Edgeport transmits/interprets as XON. | |
289 | // Note: This command MUST be sent before sending a SET_RX_FLOW or | |
290 | // SET_TX_FLOW with the XON_XOFF bit set. | |
291 | // | |
292 | // Example for Port 0 | |
293 | // P0 = 11001000 | |
294 | // P1 = IOSP_CMD_SET_XON_CHAR | |
295 | // P2 = 0x11 | |
296 | ||
297 | ||
298 | // | |
299 | // IOSP_CMD_SET_XOFF_CHAR | |
300 | // | |
301 | // Sets the character which Edgeport transmits/interprets as XOFF. | |
302 | // Note: This command must be sent before sending a SET_RX_FLOW or | |
303 | // SET_TX_FLOW with the XON_XOFF bit set. | |
304 | // | |
305 | // Example for Port 0 | |
306 | // P0 = 11001000 | |
307 | // P1 = IOSP_CMD_SET_XOFF_CHAR | |
308 | // P2 = 0x13 | |
309 | ||
310 | ||
311 | // | |
312 | // IOSP_CMD_RX_CHECK_REQ | |
313 | // | |
a3204711 GKH |
314 | // This command is used to assist in the implementation of the |
315 | // IOCTL_SERIAL_PURGE Windows IOCTL. | |
316 | // This IOSP command tries to place a marker at the end of the RX | |
317 | // queue in the Edgeport. If the Edgeport RX queue is full then | |
318 | // the Check will be discarded. | |
319 | // It is up to the device driver to timeout waiting for the | |
320 | // RX_CHECK_RSP. If a RX_CHECK_RSP is received, the driver is | |
321 | // sure that all data has been received from the edgeport and | |
1da177e4 | 322 | // may now purge any internal RX buffers. |
a3204711 | 323 | // Note tat the sequence numbers may be used to detect lost |
1da177e4 LT |
324 | // CHECK_REQs. |
325 | ||
326 | // Example for Port 0 | |
327 | // P0 = 11001000 | |
328 | // P1 = IOSP_CMD_RX_CHECK_REQ | |
329 | // P2 = Sequence number | |
330 | ||
331 | ||
332 | // Response will be: | |
333 | // P1 = IOSP_EXT_RX_CHECK_RSP | |
334 | // P2 = Request Sequence number | |
335 | ||
336 | ||
337 | ||
338 | //-------------------------------------------------------------- | |
339 | // | |
340 | // Define values for status and status parameters | |
341 | // (received by Host from Edgeport) | |
342 | // | |
343 | // 1ssssPPP P1P1P1P1 [ P2P2P2P2P2 ]... | |
344 | // | |
a3204711 | 345 | // ssss: 00-07 2-byte status. ssss identifies which UART register |
1da177e4 LT |
346 | // has changed value, and the new value is in P1. |
347 | // Note that the ssss values do not correspond to the | |
348 | // 16554 register numbers given in 16554.H. Instead, | |
349 | // see below for definitions of the ssss numbers | |
350 | // used in this status message. | |
351 | // | |
352 | // 08-0B 3-byte status: ==== P1 ==== ==== P2 ==== | |
353 | // 08 LSR_DATA: New LSR Errored byte | |
354 | // 09 1-param responses Response Code Param | |
355 | // 0A OPEN_RSP: InitialMsr TxBufferSize | |
356 | // 0B available for expansion | |
357 | // | |
358 | // 0C-0D 4-byte status. P1 = extended status code and P2,P3 = params | |
359 | // Not currently implemented. | |
360 | // | |
361 | // 0E-0F N-byte status: P1 = num bytes after P1 (ie, TotalLen - 2) | |
362 | // P2 = extended status, P3..Pn = parameters. | |
363 | // Not currently implemented. | |
364 | // | |
365 | ||
366 | /**************************************************** | |
367 | * SSSS values for 2-byte status messages (0-8) | |
368 | ****************************************************/ | |
369 | ||
370 | #define IOSP_STATUS_LSR 0x00 // P1 is new value of LSR register. | |
371 | ||
372 | // Bits defined in 16554.H. Edgeport | |
373 | // returns this in order to report | |
374 | // line status errors (overrun, | |
375 | // parity, framing, break). This form | |
376 | // is used when a errored receive data | |
377 | // character was NOT present in the | |
378 | // UART when the LSR error occurred | |
379 | // (ie, when LSR bit 0 = 0). | |
380 | ||
381 | #define IOSP_STATUS_MSR 0x01 // P1 is new value of MSR register. | |
382 | ||
383 | // Bits defined in 16554.H. Edgeport | |
384 | // returns this in order to report | |
385 | // changes in modem status lines | |
386 | // (CTS, DSR, RI, CD) | |
a3204711 | 387 | // |
1da177e4 LT |
388 | |
389 | // 0x02 // Available for future expansion | |
a3204711 GKH |
390 | // 0x03 // |
391 | // 0x04 // | |
392 | // 0x05 // | |
393 | // 0x06 // | |
394 | // 0x07 // | |
1da177e4 LT |
395 | |
396 | ||
397 | /**************************************************** | |
398 | * SSSS values for 3-byte status messages (8-A) | |
399 | ****************************************************/ | |
400 | ||
401 | #define IOSP_STATUS_LSR_DATA 0x08 // P1 is new value of LSR register (same as STATUS_LSR) | |
402 | ||
403 | // P2 is errored character read from | |
a3204711 | 404 | // RxFIFO after LSR reported an error. |
1da177e4 LT |
405 | |
406 | #define IOSP_EXT_STATUS 0x09 // P1 is status/response code, param in P2. | |
407 | ||
408 | ||
409 | // Response Codes (P1 values) for 3-byte status messages | |
410 | ||
411 | #define IOSP_EXT_STATUS_CHASE_RSP 0 // Reply to CHASE_PORT cmd. P2 is outcome: | |
a3204711 | 412 | #define IOSP_EXT_STATUS_CHASE_PASS 0 // P2 = 0: All Tx data drained successfully |
1da177e4 LT |
413 | #define IOSP_EXT_STATUS_CHASE_FAIL 1 // P2 = 1: Timed out (stuck due to flow |
414 | ||
415 | // control from remote device). | |
416 | ||
417 | #define IOSP_EXT_STATUS_RX_CHECK_RSP 1 // Reply to RX_CHECK cmd. P2 is sequence number | |
418 | ||
419 | ||
420 | #define IOSP_STATUS_OPEN_RSP 0x0A // Reply to OPEN_PORT cmd. | |
421 | ||
422 | // P1 is Initial MSR value | |
423 | // P2 is encoded TxBuffer Size: | |
424 | // TxBufferSize = (P2 + 1) * 64 | |
425 | ||
426 | // 0x0B // Available for future expansion | |
427 | ||
428 | #define GET_TX_BUFFER_SIZE(P2) (((P2) + 1) * 64) | |
429 | ||
430 | ||
431 | ||
432 | ||
433 | /**************************************************** | |
434 | * SSSS values for 4-byte status messages | |
435 | ****************************************************/ | |
436 | ||
437 | #define IOSP_EXT4_STATUS 0x0C // Extended status code in P1, | |
438 | ||
439 | // Params in P2, P3 | |
440 | // Currently unimplemented. | |
441 | ||
442 | // 0x0D // Currently unused, available. | |
443 | ||
444 | ||
445 | ||
446 | // | |
447 | // Macros to parse status messages | |
448 | // | |
449 | ||
a3204711 | 450 | #define IOSP_GET_STATUS_LEN(code) ((code) < 8 ? 2 : ((code) < 0x0A ? 3 : 4)) |
1da177e4 | 451 | |
a3204711 GKH |
452 | #define IOSP_STATUS_IS_2BYTE(code) ((code) < 0x08) |
453 | #define IOSP_STATUS_IS_3BYTE(code) (((code) >= 0x08) && ((code) <= 0x0B)) | |
454 | #define IOSP_STATUS_IS_4BYTE(code) (((code) >= 0x0C) && ((code) <= 0x0D)) | |
1da177e4 | 455 |