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 preceeded 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 { 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 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) 118 #define IS_DATA_HDR(Byte1) (! IS_CMD_STAT_HDR(Byte1)) 119 120 #define IOSP_GET_HDR_PORT(Byte1) ((__u8) ((Byte1) & IOSP_PORT_MASK)) 121 #define IOSP_GET_HDR_DATA_LEN(Byte1, Byte2) ((__u16) ( ((__u16)((Byte1) & 0x78)) << 5) | (Byte2)) 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 // 128 #define IOSP_BUILD_DATA_HDR1(Port, Len) ((__u8) (((Port) | ((__u8) (((__u16) (Len)) >> 5) & 0x78 )))) 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 // 135 #define IOSP_BUILD_CMD_HDR1(Port, Cmd) ((__u8) ( IOSP_CMD_STAT_BIT | (Port) | ((__u8) ((Cmd) << 3)) )) 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 197 #define MAKE_CMD_WRITE_REG(ppBuf, pLen, Port, Reg, Val) \ 198 do { \ 199 (*(ppBuf))[0] = IOSP_BUILD_CMD_HDR1( (Port), IOSP_WRITE_UART_REG(Reg) ); \ 200 (*(ppBuf))[1] = (Val); \ 201 \ 202 *ppBuf += 2; \ 203 *pLen += 2; \ 204 } while (0) 205 206 #define MAKE_CMD_EXT_CMD(ppBuf, pLen, Port, ExtCmd, Param) \ 207 do { \ 208 (*(ppBuf))[0] = IOSP_BUILD_CMD_HDR1( (Port), IOSP_EXT_CMD ); \ 209 (*(ppBuf))[1] = (ExtCmd); \ 210 (*(ppBuf))[2] = (Param); \ 211 \ 212 *ppBuf += 3; \ 213 *pLen += 3; \ 214 } while (0) 215 216 217 218 //-------------------------------------------------------------- 219 // 220 // Define format of flow control commands 221 // (sent from Host to Edgeport) 222 // 223 // 11001PPP FlowCmd FlowTypes 224 // 225 // Note that the 'FlowTypes' parameter is a bit mask; that is, 226 // more than one flow control type can be active at the same time. 227 // FlowTypes = 0 means 'no flow control'. 228 // 229 230 // 231 // IOSP_CMD_SET_RX_FLOW 232 // 233 // Tells Edgeport how it can stop incoming UART data 234 // 235 // Example for Port 0 236 // P0 = 11001000 237 // P1 = IOSP_CMD_SET_RX_FLOW 238 // P2 = Bit mask as follows: 239 240 #define IOSP_RX_FLOW_RTS 0x01 // Edgeport drops RTS to stop incoming data 241 #define IOSP_RX_FLOW_DTR 0x02 // Edgeport drops DTR to stop incoming data 242 #define IOSP_RX_FLOW_DSR_SENSITIVITY 0x04 // Ignores Rx data unless DSR high 243 244 // Not currently implemented by firmware. 245 #define IOSP_RX_FLOW_XON_XOFF 0x08 // Edgeport sends XOFF char to stop incoming data. 246 247 // Host must have previously programmed the 248 // XON/XOFF values with SET_XON/SET_XOFF 249 // before enabling this bit. 250 251 // 252 // IOSP_CMD_SET_TX_FLOW 253 // 254 // Tells Edgeport what signal(s) will stop it from transmitting UART data 255 // 256 // Example for Port 0 257 // P0 = 11001000 258 // P1 = IOSP_CMD_SET_TX_FLOW 259 // P2 = Bit mask as follows: 260 261 #define IOSP_TX_FLOW_CTS 0x01 // Edgeport stops Tx if CTS low 262 #define IOSP_TX_FLOW_DSR 0x02 // Edgeport stops Tx if DSR low 263 #define IOSP_TX_FLOW_DCD 0x04 // Edgeport stops Tx if DCD low 264 #define IOSP_TX_FLOW_XON_XOFF 0x08 // Edgeport stops Tx upon receiving XOFF char. 265 266 // Host must have previously programmed the 267 // XON/XOFF values with SET_XON/SET_XOFF 268 // before enabling this bit. 269 #define IOSP_TX_FLOW_XOFF_CONTINUE 0x10 // If not set, Edgeport stops Tx when 270 271 // sending XOFF in order to fix broken 272 // systems that interpret the next 273 // received char as XON. 274 // If set, Edgeport continues Tx 275 // normally after transmitting XOFF. 276 // Not currently implemented by firmware. 277 #define IOSP_TX_TOGGLE_RTS 0x20 // Edgeport drives RTS as a true half-duplex 278 279 // Request-to-Send signal: it is raised before 280 // beginning transmission and lowered after 281 // the last Tx char leaves the UART. 282 // Not currently implemented by firmware. 283 284 // 285 // IOSP_CMD_SET_XON_CHAR 286 // 287 // Sets the character which Edgeport transmits/interprets as XON. 288 // Note: This command MUST be sent before sending a SET_RX_FLOW or 289 // SET_TX_FLOW with the XON_XOFF bit set. 290 // 291 // Example for Port 0 292 // P0 = 11001000 293 // P1 = IOSP_CMD_SET_XON_CHAR 294 // P2 = 0x11 295 296 297 // 298 // IOSP_CMD_SET_XOFF_CHAR 299 // 300 // Sets the character which Edgeport transmits/interprets as XOFF. 301 // Note: This command must be sent before sending a SET_RX_FLOW or 302 // SET_TX_FLOW with the XON_XOFF bit set. 303 // 304 // Example for Port 0 305 // P0 = 11001000 306 // P1 = IOSP_CMD_SET_XOFF_CHAR 307 // P2 = 0x13 308 309 310 // 311 // IOSP_CMD_RX_CHECK_REQ 312 // 313 // This command is used to assist in the implementation of the 314 // IOCTL_SERIAL_PURGE Windows IOCTL. 315 // This IOSP command tries to place a marker at the end of the RX 316 // queue in the Edgeport. If the Edgeport RX queue is full then 317 // the Check will be discarded. 318 // It is up to the device driver to timeout waiting for the 319 // RX_CHECK_RSP. If a RX_CHECK_RSP is received, the driver is 320 // sure that all data has been received from the edgeport and 321 // may now purge any internal RX buffers. 322 // Note tat the sequence numbers may be used to detect lost 323 // CHECK_REQs. 324 325 // Example for Port 0 326 // P0 = 11001000 327 // P1 = IOSP_CMD_RX_CHECK_REQ 328 // P2 = Sequence number 329 330 331 // Response will be: 332 // P1 = IOSP_EXT_RX_CHECK_RSP 333 // P2 = Request Sequence number 334 335 336 337 //-------------------------------------------------------------- 338 // 339 // Define values for status and status parameters 340 // (received by Host from Edgeport) 341 // 342 // 1ssssPPP P1P1P1P1 [ P2P2P2P2P2 ]... 343 // 344 // ssss: 00-07 2-byte status. ssss identifies which UART register 345 // has changed value, and the new value is in P1. 346 // Note that the ssss values do not correspond to the 347 // 16554 register numbers given in 16554.H. Instead, 348 // see below for definitions of the ssss numbers 349 // used in this status message. 350 // 351 // 08-0B 3-byte status: ==== P1 ==== ==== P2 ==== 352 // 08 LSR_DATA: New LSR Errored byte 353 // 09 1-param responses Response Code Param 354 // 0A OPEN_RSP: InitialMsr TxBufferSize 355 // 0B available for expansion 356 // 357 // 0C-0D 4-byte status. P1 = extended status code and P2,P3 = params 358 // Not currently implemented. 359 // 360 // 0E-0F N-byte status: P1 = num bytes after P1 (ie, TotalLen - 2) 361 // P2 = extended status, P3..Pn = parameters. 362 // Not currently implemented. 363 // 364 365 /**************************************************** 366 * SSSS values for 2-byte status messages (0-8) 367 ****************************************************/ 368 369 #define IOSP_STATUS_LSR 0x00 // P1 is new value of LSR register. 370 371 // Bits defined in 16554.H. Edgeport 372 // returns this in order to report 373 // line status errors (overrun, 374 // parity, framing, break). This form 375 // is used when a errored receive data 376 // character was NOT present in the 377 // UART when the LSR error occurred 378 // (ie, when LSR bit 0 = 0). 379 380 #define IOSP_STATUS_MSR 0x01 // P1 is new value of MSR register. 381 382 // Bits defined in 16554.H. Edgeport 383 // returns this in order to report 384 // changes in modem status lines 385 // (CTS, DSR, RI, CD) 386 // 387 388 // 0x02 // Available for future expansion 389 // 0x03 // 390 // 0x04 // 391 // 0x05 // 392 // 0x06 // 393 // 0x07 // 394 395 396 /**************************************************** 397 * SSSS values for 3-byte status messages (8-A) 398 ****************************************************/ 399 400 #define IOSP_STATUS_LSR_DATA 0x08 // P1 is new value of LSR register (same as STATUS_LSR) 401 402 // P2 is errored character read from 403 // RxFIFO after LSR reported an error. 404 405 #define IOSP_EXT_STATUS 0x09 // P1 is status/response code, param in P2. 406 407 408 // Response Codes (P1 values) for 3-byte status messages 409 410 #define IOSP_EXT_STATUS_CHASE_RSP 0 // Reply to CHASE_PORT cmd. P2 is outcome: 411 #define IOSP_EXT_STATUS_CHASE_PASS 0 // P2 = 0: All Tx data drained successfully 412 #define IOSP_EXT_STATUS_CHASE_FAIL 1 // P2 = 1: Timed out (stuck due to flow 413 414 // control from remote device). 415 416 #define IOSP_EXT_STATUS_RX_CHECK_RSP 1 // Reply to RX_CHECK cmd. P2 is sequence number 417 418 419 #define IOSP_STATUS_OPEN_RSP 0x0A // Reply to OPEN_PORT cmd. 420 421 // P1 is Initial MSR value 422 // P2 is encoded TxBuffer Size: 423 // TxBufferSize = (P2 + 1) * 64 424 425 // 0x0B // Available for future expansion 426 427 #define GET_TX_BUFFER_SIZE(P2) (((P2) + 1) * 64) 428 429 430 431 432 /**************************************************** 433 * SSSS values for 4-byte status messages 434 ****************************************************/ 435 436 #define IOSP_EXT4_STATUS 0x0C // Extended status code in P1, 437 438 // Params in P2, P3 439 // Currently unimplemented. 440 441 // 0x0D // Currently unused, available. 442 443 444 445 // 446 // Macros to parse status messages 447 // 448 449 #define IOSP_GET_STATUS_LEN(code) ( (code) < 8 ? 2 : ((code) < 0x0A ? 3 : 4) ) 450 451 #define IOSP_STATUS_IS_2BYTE(code) ( (code) < 0x08 ) 452 #define IOSP_STATUS_IS_3BYTE(code) ( ((code) >= 0x08) && ((code) <= 0x0B) ) 453 #define IOSP_STATUS_IS_4BYTE(code) ( ((code) >= 0x0C) && ((code) <= 0x0D) ) 454 455