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

source code of linux/drivers/usb/serial/io_ionsp.h