1/* 2** ----------------------------------------------------------------------------- 3** 4** Perle Specialix driver for Linux 5** Ported from existing RIO Driver for SCO sources. 6 * 7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22** 23** Module : rioparam.c 24** SID : 1.3 25** Last Modified : 11/6/98 10:33:45 26** Retrieved : 11/6/98 10:33:50 27** 28** ident @(#)rioparam.c 1.3 29** 30** ----------------------------------------------------------------------------- 31*/ 32 33#ifdef SCCS_LABELS 34static char *_rioparam_c_sccs_ = "@(#)rioparam.c 1.3"; 35#endif 36 37#define __NO_VERSION__ 38#include <linux/module.h> 39#include <linux/slab.h> 40#include <linux/errno.h> 41#include <linux/tty.h> 42#include <asm/io.h> 43#include <asm/system.h> 44#include <asm/string.h> 45#include <asm/semaphore.h> 46#include <asm/uaccess.h> 47 48#include <linux/termios.h> 49#include <linux/serial.h> 50 51#include <linux/compatmac.h> 52#include <linux/generic_serial.h> 53 54 55#include "linux_compat.h" 56#include "rio_linux.h" 57#include "typdef.h" 58#include "pkt.h" 59#include "daemon.h" 60#include "rio.h" 61#include "riospace.h" 62#include "top.h" 63#include "cmdpkt.h" 64#include "map.h" 65#include "riotypes.h" 66#include "rup.h" 67#include "port.h" 68#include "riodrvr.h" 69#include "rioinfo.h" 70#include "func.h" 71#include "errors.h" 72#include "pci.h" 73 74#include "parmmap.h" 75#include "unixrup.h" 76#include "board.h" 77#include "host.h" 78#include "error.h" 79#include "phb.h" 80#include "link.h" 81#include "cmdblk.h" 82#include "route.h" 83#include "control.h" 84#include "cirrus.h" 85#include "rioioctl.h" 86#include "param.h" 87#include "list.h" 88#include "sam.h" 89 90 91 92/* 93** The Scam, based on email from jeremyr@bugs.specialix.co.uk.... 94** 95** To send a command on a particular port, you put a packet with the 96** command bit set onto the port. The command bit is in the len field, 97** and gets ORed in with the actual byte count. 98** 99** When you send a packet with the command bit set, then the first 100** data byte ( data[0] ) is interpretted as the command to execute. 101** It also governs what data structure overlay should accompany the packet. 102** Commands are defined in cirrus/cirrus.h 103** 104** If you want the command to pre-emt data already on the queue for the 105** port, set the pre-emptive bit in conjunction with the command bit. 106** It is not defined what will happen if you set the preemptive bit 107** on a packet that is NOT a command. 108** 109** Pre-emptive commands should be queued at the head of the queue using 110** add_start(), whereas normal commands and data are enqueued using 111** add_end(). 112** 113** Most commands do not use the remaining bytes in the data array. The 114** exceptions are OPEN MOPEN and CONFIG. (NB. As with the SI CONFIG and 115** OPEN are currently analagous). With these three commands the following 116** 11 data bytes are all used to pass config information such as baud rate etc. 117** The fields are also defined in cirrus.h. Some contain straightforward 118** information such as the transmit XON character. Two contain the transmit and 119** receive baud rates respectively. For most baud rates there is a direct 120** mapping between the rates defined in <sys/termio.h> and the byte in the 121** packet. There are additional (non UNIX-standard) rates defined in 122** /u/dos/rio/cirrus/h/brates.h. 123** 124** The rest of the data fields contain approximations to the Cirrus registers 125** that are used to program number of bits etc. Each registers bit fields is 126** defined in cirrus.h. 127** 128** NB. Only use those bits that are defined as being driver specific 129** or common to the RTA and the driver. 130** 131** All commands going from RTA->Host will be dealt with by the Host code - you 132** will never see them. As with the SI there will be three fields to look out 133** for in each phb (not yet defined - needs defining a.s.a.p). 134** 135** modem_status - current state of handshake pins. 136** 137** port_status - current port status - equivalent to hi_stat for SI, indicates 138** if port is IDLE_OPEN, IDLE_CLOSED etc. 139** 140** break_status - bit X set if break has been received. 141** 142** Happy hacking. 143** 144*/ 145 146/* 147** RIOParam is used to open or configure a port. You pass it a PortP, 148** which will have a tty struct attached to it. You also pass a command, 149** either OPEN or CONFIG. The port's setup is taken from the t_ fields 150** of the tty struct inside the PortP, and the port is either opened 151** or re-configured. You must also tell RIOParam if the device is a modem 152** device or not (i.e. top bit of minor number set or clear - take special 153** care when deciding on this!). 154** RIOParam neither flushes nor waits for drain, and is NOT preemptive. 155** 156** RIOParam assumes it will be called at splrio(), and also assumes 157** that CookMode is set correctly in the port structure. 158** 159** NB. for MPX 160** tty lock must NOT have been previously acquired. 161*/ 162int 163RIOParam(PortP, cmd, Modem, SleepFlag) 164struct Port *PortP; 165int cmd; 166int Modem; 167int SleepFlag; 168{ 169 register struct tty_struct *TtyP; 170 int retval; 171 register struct phb_param *phb_param_ptr; 172 PKT *PacketP; 173 int res; 174 uchar Cor1=0, Cor2=0, Cor4=0, Cor5=0; 175 uchar TxXon=0, TxXoff=0, RxXon=0, RxXoff=0; 176 uchar LNext=0, TxBaud=0, RxBaud=0; 177 int retries = 0xff; 178 unsigned long flags; 179 180 func_enter (); 181 182 TtyP = PortP->gs.tty; 183 184 rio_dprintk (RIO_DEBUG_PARAM, "RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n", 185 PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP); 186 187 if (!TtyP) { 188 rio_dprintk (RIO_DEBUG_PARAM, "Can't call rioparam with null tty.\n"); 189 190 func_exit (); 191 192 return RIO_FAIL; 193 } 194 rio_spin_lock_irqsave(&PortP->portSem, flags ); 195 196 if (cmd == OPEN) { 197 /* 198 ** If the port is set to store or lock the parameters, and it is 199 ** paramed with OPEN, we want to restore the saved port termio, but 200 ** only if StoredTermio has been saved, i.e. NOT 1st open after reboot. 201 */ 202 } 203 204 /* 205 ** wait for space 206 */ 207 while ( !(res=can_add_transmit(&PacketP,PortP)) || 208 (PortP->InUse != NOT_INUSE) ) { 209 if (retries -- <= 0) { 210 break; 211 } 212 if ( PortP->InUse != NOT_INUSE ) { 213 rio_dprintk (RIO_DEBUG_PARAM, "Port IN_USE for pre-emptive command\n"); 214 } 215 216 if ( !res ) { 217 rio_dprintk (RIO_DEBUG_PARAM, "Port has no space on transmit queue\n"); 218 } 219 220 if ( SleepFlag != OK_TO_SLEEP ) { 221 rio_spin_unlock_irqrestore( &PortP->portSem, flags); 222 func_exit(); 223 224 return RIO_FAIL; 225 } 226 227 rio_dprintk (RIO_DEBUG_PARAM, "wait for can_add_transmit\n"); 228 rio_spin_unlock_irqrestore( &PortP->portSem, flags); 229 retval = RIODelay(PortP, HUNDRED_MS); 230 rio_spin_lock_irqsave( &PortP->portSem, flags); 231 if (retval == RIO_FAIL) { 232 rio_dprintk (RIO_DEBUG_PARAM, "wait for can_add_transmit broken by signal\n"); 233 rio_spin_unlock_irqrestore( &PortP->portSem, flags); 234 pseterr(EINTR); 235 func_exit(); 236 237 return RIO_FAIL; 238 } 239 if ( PortP->State & RIO_DELETED ) { 240 rio_spin_unlock_irqrestore( &PortP->portSem, flags); 241 func_exit (); 242 243 return RIO_SUCCESS; 244 } 245 } 246 247 if (!res) { 248 rio_spin_unlock_irqrestore( &PortP->portSem, flags); 249 func_exit (); 250 251 return RIO_FAIL; 252 } 253 254 rio_dprintk (RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n",res); 255 rio_dprintk (RIO_DEBUG_PARAM, "Packet is 0x%x\n",(int) PacketP); 256 257 phb_param_ptr = (struct phb_param *)PacketP->data; 258 259 260 261 switch ( TtyP->termios->c_cflag & CSIZE ) { 262 case CS5: 263 { 264 rio_dprintk (RIO_DEBUG_PARAM, "5 bit data\n"); 265 Cor1 |= COR1_5BITS; 266 break; 267 } 268 case CS6: 269 { 270 rio_dprintk (RIO_DEBUG_PARAM, "6 bit data\n"); 271 Cor1 |= COR1_6BITS; 272 break; 273 } 274 case CS7: 275 { 276 rio_dprintk (RIO_DEBUG_PARAM, "7 bit data\n"); 277 Cor1 |= COR1_7BITS; 278 break; 279 } 280 case CS8: 281 { 282 rio_dprintk (RIO_DEBUG_PARAM, "8 bit data\n"); 283 Cor1 |= COR1_8BITS; 284 break; 285 } 286 } 287 288 if ( TtyP->termios->c_cflag & CSTOPB ) { 289 rio_dprintk (RIO_DEBUG_PARAM, "2 stop bits\n"); 290 Cor1 |= COR1_2STOP; 291 } 292 else { 293 rio_dprintk (RIO_DEBUG_PARAM, "1 stop bit\n"); 294 Cor1 |= COR1_1STOP; 295 } 296 297 if ( TtyP->termios->c_cflag & PARENB ) { 298 rio_dprintk (RIO_DEBUG_PARAM, "Enable parity\n"); 299 Cor1 |= COR1_NORMAL; 300 } 301 else { 302 rio_dprintk (RIO_DEBUG_PARAM, "Disable parity\n"); 303 Cor1 |= COR1_NOP; 304 } 305 if ( TtyP->termios->c_cflag & PARODD ) { 306 rio_dprintk (RIO_DEBUG_PARAM, "Odd parity\n"); 307 Cor1 |= COR1_ODD; 308 } 309 else { 310 rio_dprintk (RIO_DEBUG_PARAM, "Even parity\n"); 311 Cor1 |= COR1_EVEN; 312 } 313 314 /* 315 ** COR 2 316 */ 317 if ( TtyP->termios->c_iflag & IXON ) { 318 rio_dprintk (RIO_DEBUG_PARAM, "Enable start/stop output control\n"); 319 Cor2 |= COR2_IXON; 320 } 321 else { 322 if ( PortP->Config & RIO_IXON ) { 323 rio_dprintk (RIO_DEBUG_PARAM, "Force enable start/stop output control\n"); 324 Cor2 |= COR2_IXON; 325 } 326 else 327 rio_dprintk (RIO_DEBUG_PARAM, "IXON has been disabled.\n"); 328 } 329 330 if (TtyP->termios->c_iflag & IXANY) { 331 if ( PortP->Config & RIO_IXANY ) { 332 rio_dprintk (RIO_DEBUG_PARAM, "Enable any key to restart output\n"); 333 Cor2 |= COR2_IXANY; 334 } 335 else 336 rio_dprintk (RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n"); 337 } 338 339 if ( TtyP->termios->c_iflag & IXOFF ) { 340 rio_dprintk (RIO_DEBUG_PARAM, "Enable start/stop input control 2\n"); 341 Cor2 |= COR2_IXOFF; 342 } 343 344 if ( TtyP->termios->c_cflag & HUPCL ) { 345 rio_dprintk (RIO_DEBUG_PARAM, "Hangup on last close\n"); 346 Cor2 |= COR2_HUPCL; 347 } 348 349 if ( C_CRTSCTS (TtyP)) { 350 rio_dprintk (RIO_DEBUG_PARAM, "Rx hardware flow control enabled\n"); 351 Cor2 |= COR2_CTSFLOW; 352 Cor2 |= COR2_RTSFLOW; 353 } else { 354 rio_dprintk (RIO_DEBUG_PARAM, "Rx hardware flow control disabled\n"); 355 Cor2 &= ~COR2_CTSFLOW; 356 Cor2 &= ~COR2_RTSFLOW; 357 } 358 359 360 if ( TtyP->termios->c_cflag & CLOCAL ) { 361 rio_dprintk (RIO_DEBUG_PARAM, "Local line\n"); 362 } 363 else { 364 rio_dprintk (RIO_DEBUG_PARAM, "Possible Modem line\n"); 365 } 366 367 /* 368 ** COR 4 (there is no COR 3) 369 */ 370 if ( TtyP->termios->c_iflag & IGNBRK ) { 371 rio_dprintk (RIO_DEBUG_PARAM, "Ignore break condition\n"); 372 Cor4 |= COR4_IGNBRK; 373 } 374 if ( !(TtyP->termios->c_iflag & BRKINT) ) { 375 rio_dprintk (RIO_DEBUG_PARAM, "Break generates NULL condition\n"); 376 Cor4 |= COR4_NBRKINT; 377 } else { 378 rio_dprintk (RIO_DEBUG_PARAM, "Interrupt on break condition\n"); 379 } 380 381 if ( TtyP->termios->c_iflag & INLCR ) { 382 rio_dprintk (RIO_DEBUG_PARAM, "Map newline to carriage return on input\n"); 383 Cor4 |= COR4_INLCR; 384 } 385 386 if ( TtyP->termios->c_iflag & IGNCR ) { 387 rio_dprintk (RIO_DEBUG_PARAM, "Ignore carriage return on input\n"); 388 Cor4 |= COR4_IGNCR; 389 } 390 391 if ( TtyP->termios->c_iflag & ICRNL ) { 392 rio_dprintk (RIO_DEBUG_PARAM, "Map carriage return to newline on input\n"); 393 Cor4 |= COR4_ICRNL; 394 } 395 if ( TtyP->termios->c_iflag & IGNPAR ) { 396 rio_dprintk (RIO_DEBUG_PARAM, "Ignore characters with parity errors\n"); 397 Cor4 |= COR4_IGNPAR; 398 } 399 if ( TtyP->termios->c_iflag & PARMRK ) { 400 rio_dprintk (RIO_DEBUG_PARAM, "Mark parity errors\n"); 401 Cor4 |= COR4_PARMRK; 402 } 403 404 /* 405 ** Set the RAISEMOD flag to ensure that the modem lines are raised 406 ** on reception of a config packet. 407 ** The download code handles the zero baud condition. 408 */ 409 Cor4 |= COR4_RAISEMOD; 410 411 /* 412 ** COR 5 413 */ 414 415 Cor5 = COR5_CMOE; 416 417 /* 418 ** Set to monitor tbusy/tstop (or not). 419 */ 420 421 if (PortP->MonitorTstate) 422 Cor5 |= COR5_TSTATE_ON; 423 else 424 Cor5 |= COR5_TSTATE_OFF; 425 426 /* 427 ** Could set LNE here if you wanted LNext processing. SVR4 will use it. 428 */ 429 if ( TtyP->termios->c_iflag & ISTRIP ) { 430 rio_dprintk (RIO_DEBUG_PARAM, "Strip input characters\n"); 431 if (! (PortP->State & RIO_TRIAD_MODE)) { 432 Cor5 |= COR5_ISTRIP; 433 } 434 } 435 436 if ( TtyP->termios->c_oflag & ONLCR ) { 437 rio_dprintk (RIO_DEBUG_PARAM, "Map newline to carriage-return, newline on output\n"); 438 if ( PortP->CookMode == COOK_MEDIUM ) 439 Cor5 |= COR5_ONLCR; 440 } 441 if ( TtyP->termios->c_oflag & OCRNL ) { 442 rio_dprintk (RIO_DEBUG_PARAM, "Map carriage return to newline on output\n"); 443 if ( PortP->CookMode == COOK_MEDIUM ) 444 Cor5 |= COR5_OCRNL; 445 } 446 if ( ( TtyP->termios->c_oflag & TABDLY) == TAB3 ) { 447 rio_dprintk (RIO_DEBUG_PARAM, "Tab delay 3 set\n"); 448 if ( PortP->CookMode == COOK_MEDIUM ) 449 Cor5 |= COR5_TAB3; 450 } 451 452 /* 453 ** Flow control bytes. 454 */ 455 TxXon = TtyP->termios->c_cc[VSTART]; 456 TxXoff = TtyP->termios->c_cc[VSTOP]; 457 RxXon = TtyP->termios->c_cc[VSTART]; 458 RxXoff = TtyP->termios->c_cc[VSTOP]; 459 /* 460 ** LNEXT byte 461 */ 462 LNext = 0; 463 464 /* 465 ** Baud rate bytes 466 */ 467 rio_dprintk (RIO_DEBUG_PARAM, "Mapping of rx/tx baud %x (%x)\n", 468 TtyP->termios->c_cflag, CBAUD); 469 470 switch (TtyP->termios->c_cflag & CBAUD) { 471#define e(b) case B ## b : RxBaud = TxBaud = RIO_B ## b ;break 472 e(50);e(75);e(110);e(134);e(150);e(200);e(300);e(600);e(1200); 473 e(1800);e(2400);e(4800);e(9600);e(19200);e(38400);e(57600); 474 e(115200); /* e(230400);e(460800); e(921600); */ 475 } 476 477 /* (TtyP->termios->c_cflag & V_CBAUD); */ 478 479 rio_dprintk (RIO_DEBUG_PARAM, "tx baud 0x%x, rx baud 0x%x\n", TxBaud, RxBaud); 480 481 482 /* 483 ** Leftovers 484 */ 485 if ( TtyP->termios->c_cflag & CREAD ) 486 rio_dprintk (RIO_DEBUG_PARAM, "Enable receiver\n"); 487#ifdef RCV1EN 488 if ( TtyP->termios->c_cflag & RCV1EN ) 489 rio_dprintk (RIO_DEBUG_PARAM, "RCV1EN (?)\n"); 490#endif 491#ifdef XMT1EN 492 if ( TtyP->termios->c_cflag & XMT1EN ) 493 rio_dprintk (RIO_DEBUG_PARAM, "XMT1EN (?)\n"); 494#endif 495 if ( TtyP->termios->c_lflag & ISIG ) 496 rio_dprintk (RIO_DEBUG_PARAM, "Input character signal generating enabled\n"); 497 if ( TtyP->termios->c_lflag & ICANON ) 498 rio_dprintk (RIO_DEBUG_PARAM, "Canonical input: erase and kill enabled\n"); 499 if ( TtyP->termios->c_lflag & XCASE ) 500 rio_dprintk (RIO_DEBUG_PARAM, "Canonical upper/lower presentation\n"); 501 if ( TtyP->termios->c_lflag & ECHO ) 502 rio_dprintk (RIO_DEBUG_PARAM, "Enable input echo\n"); 503 if ( TtyP->termios->c_lflag & ECHOE ) 504 rio_dprintk (RIO_DEBUG_PARAM, "Enable echo erase\n"); 505 if ( TtyP->termios->c_lflag & ECHOK ) 506 rio_dprintk (RIO_DEBUG_PARAM, "Enable echo kill\n"); 507 if ( TtyP->termios->c_lflag & ECHONL ) 508 rio_dprintk (RIO_DEBUG_PARAM, "Enable echo newline\n"); 509 if ( TtyP->termios->c_lflag & NOFLSH ) 510 rio_dprintk (RIO_DEBUG_PARAM, "Disable flush after interrupt or quit\n"); 511#ifdef TOSTOP 512 if ( TtyP->termios->c_lflag & TOSTOP ) 513 rio_dprintk (RIO_DEBUG_PARAM, "Send SIGTTOU for background output\n"); 514#endif 515#ifdef XCLUDE 516 if ( TtyP->termios->c_lflag & XCLUDE ) 517 rio_dprintk (RIO_DEBUG_PARAM, "Exclusive use of this line\n"); 518#endif 519 if ( TtyP->termios->c_iflag & IUCLC ) 520 rio_dprintk (RIO_DEBUG_PARAM, "Map uppercase to lowercase on input\n"); 521 if ( TtyP->termios->c_oflag & OPOST ) 522 rio_dprintk (RIO_DEBUG_PARAM, "Enable output post-processing\n"); 523 if ( TtyP->termios->c_oflag & OLCUC ) 524 rio_dprintk (RIO_DEBUG_PARAM, "Map lowercase to uppercase on output\n"); 525 if ( TtyP->termios->c_oflag & ONOCR ) 526 rio_dprintk (RIO_DEBUG_PARAM, "No carriage return output at column 0\n"); 527 if ( TtyP->termios->c_oflag & ONLRET ) 528 rio_dprintk (RIO_DEBUG_PARAM, "Newline performs carriage return function\n"); 529 if ( TtyP->termios->c_oflag & OFILL ) 530 rio_dprintk (RIO_DEBUG_PARAM, "Use fill characters for delay\n"); 531 if ( TtyP->termios->c_oflag & OFDEL ) 532 rio_dprintk (RIO_DEBUG_PARAM, "Fill character is DEL\n"); 533 if ( TtyP->termios->c_oflag & NLDLY ) 534 rio_dprintk (RIO_DEBUG_PARAM, "Newline delay set\n"); 535 if ( TtyP->termios->c_oflag & CRDLY ) 536 rio_dprintk (RIO_DEBUG_PARAM, "Carriage return delay set\n"); 537 if ( TtyP->termios->c_oflag & TABDLY ) 538 rio_dprintk (RIO_DEBUG_PARAM, "Tab delay set\n"); 539 /* 540 ** These things are kind of useful in a later life! 541 */ 542 PortP->Cor2Copy = Cor2; 543 544 if ( PortP->State & RIO_DELETED ) { 545 rio_spin_unlock_irqrestore( &PortP->portSem, flags); 546 func_exit (); 547 548 return RIO_FAIL; 549 } 550 551 /* 552 ** Actually write the info into the packet to be sent 553 */ 554 WBYTE(phb_param_ptr->Cmd, cmd); 555 WBYTE(phb_param_ptr->Cor1, Cor1); 556 WBYTE(phb_param_ptr->Cor2, Cor2); 557 WBYTE(phb_param_ptr->Cor4, Cor4); 558 WBYTE(phb_param_ptr->Cor5, Cor5); 559 WBYTE(phb_param_ptr->TxXon, TxXon); 560 WBYTE(phb_param_ptr->RxXon, RxXon); 561 WBYTE(phb_param_ptr->TxXoff, TxXoff); 562 WBYTE(phb_param_ptr->RxXoff, RxXoff); 563 WBYTE(phb_param_ptr->LNext, LNext); 564 WBYTE(phb_param_ptr->TxBaud, TxBaud); 565 WBYTE(phb_param_ptr->RxBaud, RxBaud); 566 567 /* 568 ** Set the length/command field 569 */ 570 WBYTE(PacketP->len , 12 | PKT_CMD_BIT); 571 572 /* 573 ** The packet is formed - now, whack it off 574 ** to its final destination: 575 */ 576 add_transmit(PortP); 577 /* 578 ** Count characters transmitted for port statistics reporting 579 */ 580 if (PortP->statsGather) 581 PortP->txchars += 12; 582 583 rio_spin_unlock_irqrestore( &PortP->portSem, flags); 584 585 rio_dprintk (RIO_DEBUG_PARAM, "add_transmit returned.\n"); 586 /* 587 ** job done. 588 */ 589 func_exit (); 590 591 return RIO_SUCCESS; 592} 593 594 595/* 596** We can add another packet to a transmit queue if the packet pointer pointed 597** to by the TxAdd pointer has PKT_IN_USE clear in its address. 598*/ 599int 600can_add_transmit(PktP, PortP) 601PKT **PktP; 602struct Port *PortP; 603{ 604 register PKT *tp; 605 606 *PktP = tp = (PKT *)RIO_PTR(PortP->Caddr,RWORD(*PortP->TxAdd)); 607 608 return !((uint)tp & PKT_IN_USE); 609} 610 611/* 612** To add a packet to the queue, you set the PKT_IN_USE bit in the address, 613** and then move the TxAdd pointer along one position to point to the next 614** packet pointer. You must wrap the pointer from the end back to the start. 615*/ 616void 617add_transmit(PortP) 618struct Port *PortP; 619{ 620 if (RWORD(*PortP->TxAdd) & PKT_IN_USE) { 621 rio_dprintk (RIO_DEBUG_PARAM, "add_transmit: Packet has been stolen!"); 622 } 623 WWORD( *(ushort *)PortP->TxAdd, RWORD(*PortP->TxAdd) | PKT_IN_USE); 624 PortP->TxAdd = (PortP->TxAdd == PortP->TxEnd) ? PortP->TxStart : 625 PortP->TxAdd + 1; 626 WWORD( PortP->PhbP->tx_add , RIO_OFF(PortP->Caddr,PortP->TxAdd) ); 627} 628 629/**************************************** 630 * Put a packet onto the end of the 631 * free list 632 ****************************************/ 633void 634put_free_end(HostP, PktP) 635struct Host *HostP; 636PKT *PktP; 637{ 638 FREE_LIST *tmp_pointer; 639 ushort old_end, new_end; 640 unsigned long flags; 641 642 rio_spin_lock_irqsave(&HostP->HostLock, flags); 643 644 /************************************************* 645 * Put a packet back onto the back of the free list 646 * 647 ************************************************/ 648 649 rio_dprintk (RIO_DEBUG_PFE, "put_free_end(PktP=%x)\n",(int)PktP); 650 651 if ((old_end=RWORD(HostP->ParmMapP->free_list_end)) != TPNULL) { 652 new_end = RIO_OFF(HostP->Caddr,PktP); 653 tmp_pointer = (FREE_LIST *)RIO_PTR(HostP->Caddr,old_end); 654 WWORD(tmp_pointer->next , new_end ); 655 WWORD(((FREE_LIST *)PktP)->prev , old_end); 656 WWORD(((FREE_LIST *)PktP)->next , TPNULL); 657 WWORD(HostP->ParmMapP->free_list_end, new_end); 658 } 659 else { /* First packet on the free list this should never happen! */ 660 rio_dprintk (RIO_DEBUG_PFE, "put_free_end(): This should never happen\n"); 661 WWORD(HostP->ParmMapP->free_list_end , RIO_OFF(HostP->Caddr,PktP)); 662 tmp_pointer = (FREE_LIST *)PktP; 663 WWORD(tmp_pointer->prev , TPNULL); 664 WWORD(tmp_pointer->next , TPNULL); 665 } 666 rio_dprintk (RIO_DEBUG_CMD, "Before unlock: %p\n", &HostP->HostLock); 667 rio_spin_unlock_irqrestore(&HostP->HostLock, flags); 668} 669 670/* 671** can_remove_receive(PktP,P) returns non-zero if PKT_IN_USE is set 672** for the next packet on the queue. It will also set PktP to point to the 673** relevent packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear, 674** then can_remove_receive() returns 0. 675*/ 676int 677can_remove_receive(PktP, PortP) 678PKT **PktP; 679struct Port *PortP; 680{ 681 if ( RWORD(*PortP->RxRemove) & PKT_IN_USE) { 682 *PktP = (PKT *)RIO_PTR(PortP->Caddr, 683 RWORD(*PortP->RxRemove) & ~PKT_IN_USE); 684 return 1; 685 } 686 return 0; 687} 688 689/* 690** To remove a packet from the receive queue you clear its PKT_IN_USE bit, 691** and then bump the pointers. Once the pointers get to the end, they must 692** be wrapped back to the start. 693*/ 694void 695remove_receive(PortP) 696struct Port *PortP; 697{ 698 WWORD( *PortP->RxRemove, RWORD(*PortP->RxRemove) & ~PKT_IN_USE ); 699 PortP->RxRemove = (PortP->RxRemove == PortP->RxEnd) ? PortP->RxStart : 700 PortP->RxRemove + 1; 701 WWORD( PortP->PhbP->rx_remove , RIO_OFF(PortP->Caddr, PortP->RxRemove) ); 702} 703