1/* 2** ----------------------------------------------------------------------------- 3** 4** Perle Specialix driver for Linux 5** ported from the existing SCO driver source 6** 7 * 8 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23** 24** Module : riocmd.c 25** SID : 1.2 26** Last Modified : 11/6/98 10:33:41 27** Retrieved : 11/6/98 10:33:49 28** 29** ident @(#)riocmd.c 1.2 30** 31** ----------------------------------------------------------------------------- 32*/ 33#ifdef SCCS_LABELS 34static char *_riocmd_c_sccs_ = "@(#)riocmd.c 1.2"; 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 47#include <linux/termios.h> 48#include <linux/serial.h> 49 50#include <linux/compatmac.h> 51#include <linux/generic_serial.h> 52 53#include "linux_compat.h" 54#include "rio_linux.h" 55#include "typdef.h" 56#include "pkt.h" 57#include "daemon.h" 58#include "rio.h" 59#include "riospace.h" 60#include "top.h" 61#include "cmdpkt.h" 62#include "map.h" 63#include "riotypes.h" 64#include "rup.h" 65#include "port.h" 66#include "riodrvr.h" 67#include "rioinfo.h" 68#include "func.h" 69#include "errors.h" 70#include "pci.h" 71 72#include "parmmap.h" 73#include "unixrup.h" 74#include "board.h" 75#include "host.h" 76#include "error.h" 77#include "phb.h" 78#include "link.h" 79#include "cmdblk.h" 80#include "route.h" 81#include "control.h" 82#include "cirrus.h" 83 84 85static struct IdentifyRta IdRta; 86static struct KillNeighbour KillUnit; 87 88int 89RIOFoadRta(HostP, MapP) 90struct Host * HostP; 91struct Map * MapP; 92{ 93 struct CmdBlk *CmdBlkP; 94 95 rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA\n"); 96 97 CmdBlkP = RIOGetCmdBlk(); 98 99 if ( !CmdBlkP ) { 100 rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: GetCmdBlk failed\n"); 101 return ENXIO; 102 } 103 104 CmdBlkP->Packet.dest_unit = MapP->ID; 105 CmdBlkP->Packet.dest_port = BOOT_RUP; 106 CmdBlkP->Packet.src_unit = 0; 107 CmdBlkP->Packet.src_port = BOOT_RUP; 108 CmdBlkP->Packet.len = 0x84; 109 CmdBlkP->Packet.data[0] = IFOAD; 110 CmdBlkP->Packet.data[1] = 0; 111 CmdBlkP->Packet.data[2] = IFOAD_MAGIC & 0xFF; 112 CmdBlkP->Packet.data[3] = (IFOAD_MAGIC >> 8) & 0xFF; 113 114 if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) { 115 rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: Failed to queue foad command\n"); 116 return EIO; 117 } 118 return 0; 119} 120 121int 122RIOZombieRta(HostP, MapP) 123struct Host * HostP; 124struct Map * MapP; 125{ 126 struct CmdBlk *CmdBlkP; 127 128 rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA\n"); 129 130 CmdBlkP = RIOGetCmdBlk(); 131 132 if ( !CmdBlkP ) { 133 rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: GetCmdBlk failed\n"); 134 return ENXIO; 135 } 136 137 CmdBlkP->Packet.dest_unit = MapP->ID; 138 CmdBlkP->Packet.dest_port = BOOT_RUP; 139 CmdBlkP->Packet.src_unit = 0; 140 CmdBlkP->Packet.src_port = BOOT_RUP; 141 CmdBlkP->Packet.len = 0x84; 142 CmdBlkP->Packet.data[0] = ZOMBIE; 143 CmdBlkP->Packet.data[1] = 0; 144 CmdBlkP->Packet.data[2] = ZOMBIE_MAGIC & 0xFF; 145 CmdBlkP->Packet.data[3] = (ZOMBIE_MAGIC >> 8) & 0xFF; 146 147 if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) { 148 rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: Failed to queue zombie command\n"); 149 return EIO; 150 } 151 return 0; 152} 153 154int 155RIOCommandRta(p, RtaUnique, func) 156struct rio_info * p; 157uint RtaUnique; 158int (* func)( struct Host *HostP, struct Map *MapP ); 159{ 160 uint Host; 161 162 rio_dprintk (RIO_DEBUG_CMD, "Command RTA 0x%x func 0x%x\n", RtaUnique, (int)func); 163 164 if ( !RtaUnique ) 165 return(0); 166 167 for ( Host = 0; Host < p->RIONumHosts; Host++ ) { 168 uint Rta; 169 struct Host *HostP = &p->RIOHosts[Host]; 170 171 for ( Rta = 0; Rta < RTAS_PER_HOST; Rta++ ) { 172 struct Map *MapP = &HostP->Mapping[Rta]; 173 174 if ( MapP->RtaUniqueNum == RtaUnique ) { 175 uint Link; 176 177 /* 178 ** now, lets just check we have a route to it... 179 ** IF the routing stuff is working, then one of the 180 ** topology entries for this unit will have a legit 181 ** route *somewhere*. We care not where - if its got 182 ** any connections, we can get to it. 183 */ 184 for ( Link = 0; Link < LINKS_PER_UNIT; Link++ ) { 185 if ( MapP->Topology[Link].Unit <= (uchar)MAX_RUP ) { 186 /* 187 ** Its worth trying the operation... 188 */ 189 return (*func)( HostP, MapP ); 190 } 191 } 192 } 193 } 194 } 195 return ENXIO; 196} 197 198 199int 200RIOIdentifyRta(p, arg) 201struct rio_info * p; 202caddr_t arg; 203{ 204 uint Host; 205 206 if ( copyin( (int)arg, (caddr_t)&IdRta, sizeof(IdRta) ) == COPYFAIL ) { 207 rio_dprintk (RIO_DEBUG_CMD, "RIO_IDENTIFY_RTA copy failed\n"); 208 p->RIOError.Error = COPYIN_FAILED; 209 return EFAULT; 210 } 211 212 for ( Host = 0 ; Host < p->RIONumHosts; Host++ ) { 213 uint Rta; 214 struct Host *HostP = &p->RIOHosts[Host]; 215 216 for ( Rta = 0; Rta < RTAS_PER_HOST; Rta++ ) { 217 struct Map *MapP = &HostP->Mapping[Rta]; 218 219 if ( MapP->RtaUniqueNum == IdRta.RtaUnique ) { 220 uint Link; 221 /* 222 ** now, lets just check we have a route to it... 223 ** IF the routing stuff is working, then one of the 224 ** topology entries for this unit will have a legit 225 ** route *somewhere*. We care not where - if its got 226 ** any connections, we can get to it. 227 */ 228 for ( Link = 0; Link < LINKS_PER_UNIT; Link++ ) { 229 if ( MapP->Topology[Link].Unit <= (uchar)MAX_RUP ) { 230 /* 231 ** Its worth trying the operation... 232 */ 233 struct CmdBlk *CmdBlkP; 234 235 rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA\n"); 236 237 CmdBlkP = RIOGetCmdBlk(); 238 239 if ( !CmdBlkP ) { 240 rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: GetCmdBlk failed\n"); 241 return ENXIO; 242 } 243 244 CmdBlkP->Packet.dest_unit = MapP->ID; 245 CmdBlkP->Packet.dest_port = BOOT_RUP; 246 CmdBlkP->Packet.src_unit = 0; 247 CmdBlkP->Packet.src_port = BOOT_RUP; 248 CmdBlkP->Packet.len = 0x84; 249 CmdBlkP->Packet.data[0] = IDENTIFY; 250 CmdBlkP->Packet.data[1] = 0; 251 CmdBlkP->Packet.data[2] = IdRta.ID; 252 253 if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) { 254 rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: Failed to queue command\n"); 255 return EIO; 256 } 257 return 0; 258 } 259 } 260 } 261 } 262 } 263 return ENOENT; 264} 265 266 267int 268RIOKillNeighbour(p, arg) 269struct rio_info * p; 270caddr_t arg; 271{ 272 uint Host; 273 uint ID; 274 struct Host *HostP; 275 struct CmdBlk *CmdBlkP; 276 277 rio_dprintk (RIO_DEBUG_CMD, "KILL HOST NEIGHBOUR\n"); 278 279 if ( copyin( (int)arg, (caddr_t)&KillUnit, sizeof(KillUnit) ) == COPYFAIL ) { 280 rio_dprintk (RIO_DEBUG_CMD, "RIO_KILL_NEIGHBOUR copy failed\n"); 281 p->RIOError.Error = COPYIN_FAILED; 282 return EFAULT; 283 } 284 285 if ( KillUnit.Link > 3 ) 286 return ENXIO; 287 288 CmdBlkP = RIOGetCmdBlk(); 289 290 if ( !CmdBlkP ) { 291 rio_dprintk (RIO_DEBUG_CMD, "UFOAD: GetCmdBlk failed\n"); 292 return ENXIO; 293 } 294 295 CmdBlkP->Packet.dest_unit = 0; 296 CmdBlkP->Packet.src_unit = 0; 297 CmdBlkP->Packet.dest_port = BOOT_RUP; 298 CmdBlkP->Packet.src_port = BOOT_RUP; 299 CmdBlkP->Packet.len = 0x84; 300 CmdBlkP->Packet.data[0] = UFOAD; 301 CmdBlkP->Packet.data[1] = KillUnit.Link; 302 CmdBlkP->Packet.data[2] = UFOAD_MAGIC & 0xFF; 303 CmdBlkP->Packet.data[3] = (UFOAD_MAGIC >> 8) & 0xFF; 304 305 for ( Host = 0; Host < p->RIONumHosts; Host++ ) { 306 ID = 0; 307 HostP = &p->RIOHosts[Host]; 308 309 if ( HostP->UniqueNum == KillUnit.UniqueNum ) { 310 if ( RIOQueueCmdBlk( HostP, RTAS_PER_HOST+KillUnit.Link, 311 CmdBlkP) == RIO_FAIL ) { 312 rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n"); 313 return EIO; 314 } 315 return 0; 316 } 317 318 for ( ID=0; ID < RTAS_PER_HOST; ID++ ) { 319 if ( HostP->Mapping[ID].RtaUniqueNum == KillUnit.UniqueNum ) { 320 CmdBlkP->Packet.dest_unit = ID+1; 321 if ( RIOQueueCmdBlk( HostP, ID, CmdBlkP) == RIO_FAIL ) { 322 rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n"); 323 return EIO; 324 } 325 return 0; 326 } 327 } 328 } 329 RIOFreeCmdBlk( CmdBlkP ); 330 return ENXIO; 331} 332 333int 334RIOSuspendBootRta(HostP, ID, Link) 335struct Host *HostP; 336int ID; 337int Link; 338{ 339 struct CmdBlk *CmdBlkP; 340 341 rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link); 342 343 CmdBlkP = RIOGetCmdBlk(); 344 345 if ( !CmdBlkP ) { 346 rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: GetCmdBlk failed\n"); 347 return ENXIO; 348 } 349 350 CmdBlkP->Packet.dest_unit = ID; 351 CmdBlkP->Packet.dest_port = BOOT_RUP; 352 CmdBlkP->Packet.src_unit = 0; 353 CmdBlkP->Packet.src_port = BOOT_RUP; 354 CmdBlkP->Packet.len = 0x84; 355 CmdBlkP->Packet.data[0] = IWAIT; 356 CmdBlkP->Packet.data[1] = Link; 357 CmdBlkP->Packet.data[2] = IWAIT_MAGIC & 0xFF; 358 CmdBlkP->Packet.data[3] = (IWAIT_MAGIC >> 8) & 0xFF; 359 360 if ( RIOQueueCmdBlk( HostP, ID - 1, CmdBlkP) == RIO_FAIL ) { 361 rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: Failed to queue iwait command\n"); 362 return EIO; 363 } 364 return 0; 365} 366 367int 368RIOFoadWakeup(p) 369struct rio_info * p; 370{ 371 int port; 372 register struct Port *PortP; 373 unsigned long flags; 374 375 for ( port=0; port<RIO_PORTS; port++) { 376 PortP = p->RIOPortp[port]; 377 378 rio_spin_lock_irqsave(&PortP->portSem, flags); 379 PortP->Config = 0; 380 PortP->State = 0; 381 PortP->InUse = NOT_INUSE; 382 PortP->PortState = 0; 383 PortP->FlushCmdBodge = 0; 384 PortP->ModemLines = 0; 385 PortP->ModemState = 0; 386 PortP->CookMode = 0; 387 PortP->ParamSem = 0; 388 PortP->Mapped = 0; 389 PortP->WflushFlag = 0; 390 PortP->MagicFlags = 0; 391 PortP->RxDataStart = 0; 392 PortP->TxBufferIn = 0; 393 PortP->TxBufferOut = 0; 394 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 395 } 396 return(0); 397} 398 399/* 400** Incoming command on the COMMAND_RUP to be processed. 401*/ 402int 403RIOCommandRup(p, Rup, HostP, PacketP) 404struct rio_info * p; 405uint Rup; 406struct Host *HostP; 407PKT *PacketP; 408{ 409 struct PktCmd *PktCmdP = (struct PktCmd *)PacketP->data; 410 struct Port *PortP; 411 struct UnixRup *UnixRupP; 412 ushort SysPort; 413 ushort ReportedModemStatus; 414 ushort rup; 415 ushort subCommand; 416 unsigned long flags; 417 418 func_enter (); 419 420#ifdef CHECK 421 CheckHost( Host ); 422 CheckHostP( HostP ); 423 CheckPacketP( PacketP ); 424#endif 425 426 /* 427 ** 16 port RTA note: 428 ** Command rup packets coming from the RTA will have pkt->data[1] (which 429 ** translates to PktCmdP->PhbNum) set to the host port number for the 430 ** particular unit. To access the correct BaseSysPort for a 16 port RTA, 431 ** we can use PhbNum to get the rup number for the appropriate 8 port 432 ** block (for the first block, this should be equal to 'Rup'). 433 */ 434 rup = RBYTE(PktCmdP->PhbNum) / (ushort)PORTS_PER_RTA; 435 UnixRupP = &HostP->UnixRups[rup]; 436 SysPort = UnixRupP->BaseSysPort + 437 (RBYTE(PktCmdP->PhbNum) % (ushort)PORTS_PER_RTA); 438 rio_dprintk (RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort); 439 440#ifdef CHECK 441 CheckRup( rup ); 442 CheckUnixRupP( UnixRupP ); 443#endif 444 if ( UnixRupP->BaseSysPort == NO_PORT ) { 445 rio_dprintk (RIO_DEBUG_CMD, "OBSCURE ERROR!\n"); 446 rio_dprintk (RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n"); 447 rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Host number %d, name ``%s''\n", 448 HostP-p->RIOHosts, HostP->Name ); 449 rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Rup number 0x%x\n", rup); 450 451 if ( Rup >= (ushort)MAX_RUP ) { 452 rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n", 453 HostP->Mapping[Rup].Name); 454 } else 455 rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", 456 ('A' + Rup - MAX_RUP), HostP->Name); 457 458 rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n", 459 PacketP->dest_unit, PacketP->dest_port ); 460 rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Source 0x%x:0x%x\n", 461 PacketP->src_unit, PacketP->src_port ); 462 rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Length 0x%x (%d)\n", PacketP->len,PacketP->len ); 463 rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Control 0x%x (%d)\n", PacketP->control, PacketP->control); 464 rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Check 0x%x (%d)\n", PacketP->csum, PacketP->csum ); 465 rio_dprintk (RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, " 466 "Command Code 0x%x\n", PktCmdP->PhbNum, PktCmdP->Command ); 467 return TRUE; 468 } 469 470#ifdef CHECK 471 CheckSysPort( SysPort ); 472#endif 473 PortP = p->RIOPortp[ SysPort ]; 474 rio_spin_lock_irqsave(&PortP->portSem, flags); 475 switch( RBYTE(PktCmdP->Command) ) { 476 case BREAK_RECEIVED: 477 rio_dprintk (RIO_DEBUG_CMD, "Received a break!\n"); 478 /* If the current line disc. is not multi-threading and 479 the current processor is not the default, reset rup_intr 480 and return FALSE to ensure that the command packet is 481 not freed. */ 482 /* Call tmgr HANGUP HERE */ 483 /* Fix this later when every thing works !!!! RAMRAJ */ 484 gs_got_break (&PortP->gs); 485 break; 486 487 case COMPLETE: 488 rio_dprintk (RIO_DEBUG_CMD, "Command complete on phb %d host %d\n", 489 RBYTE(PktCmdP->PhbNum), HostP-p->RIOHosts); 490 subCommand = 1; 491 switch (RBYTE(PktCmdP->SubCommand)) { 492 case MEMDUMP : 493 rio_dprintk (RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n", 494 RBYTE(PktCmdP->SubCommand), RWORD(PktCmdP->SubAddr)); 495 break; 496 case READ_REGISTER : 497 rio_dprintk (RIO_DEBUG_CMD, "Read register (0x%x)\n", RWORD(PktCmdP->SubAddr)); 498 p->CdRegister = (RBYTE(PktCmdP->ModemStatus) & MSVR1_HOST); 499 break; 500 default : 501 subCommand = 0; 502 break; 503 } 504 if (subCommand) 505 break; 506 rio_dprintk (RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n", 507 RBYTE(PktCmdP->PortStatus),PortP->PortState); 508 if (PortP->PortState != RBYTE(PktCmdP->PortStatus)) { 509 rio_dprintk (RIO_DEBUG_CMD, "Mark status & wakeup\n"); 510 PortP->PortState = RBYTE(PktCmdP->PortStatus); 511 /* What should we do here ... 512 wakeup( &PortP->PortState ); 513 */ 514 } else 515 rio_dprintk (RIO_DEBUG_CMD, "No change\n"); 516 517 /* FALLTHROUGH */ 518 case MODEM_STATUS: 519 /* 520 ** Knock out the tbusy and tstop bits, as these are not relevant 521 ** to the check for modem status change (they're just there because 522 ** it's a convenient place to put them!). 523 */ 524 ReportedModemStatus = RBYTE(PktCmdP->ModemStatus); 525 if ((PortP->ModemState & MSVR1_HOST) == 526 (ReportedModemStatus & MSVR1_HOST)) { 527 rio_dprintk (RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState); 528 /* 529 ** Update ModemState just in case tbusy or tstop states have 530 ** changed. 531 */ 532 PortP->ModemState = ReportedModemStatus; 533 } 534 else { 535 rio_dprintk (RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%x\n", 536 PortP->ModemState, ReportedModemStatus); 537 PortP->ModemState = ReportedModemStatus; 538#ifdef MODEM_SUPPORT 539 if ( PortP->Mapped ) { 540 /***********************************************************\ 541 ************************************************************* 542 *** *** 543 *** M O D E M S T A T E C H A N G E *** 544 *** *** 545 ************************************************************* 546 \***********************************************************/ 547 /* 548 ** If the device is a modem, then check the modem 549 ** carrier. 550 */ 551 if (PortP->gs.tty == NULL) 552 break; 553 if (PortP->gs.tty->termios == NULL) 554 break; 555 556 if (!(PortP->gs.tty->termios->c_cflag & CLOCAL) && 557 ((PortP->State & (RIO_MOPEN|RIO_WOPEN)))) { 558 559 rio_dprintk (RIO_DEBUG_CMD, "Is there a Carrier?\n"); 560 /* 561 ** Is there a carrier? 562 */ 563 if ( PortP->ModemState & MSVR1_CD ) { 564 /* 565 ** Has carrier just appeared? 566 */ 567 if (!(PortP->State & RIO_CARR_ON)) { 568 rio_dprintk (RIO_DEBUG_CMD, "Carrier just came up.\n"); 569 PortP->State |= RIO_CARR_ON; 570 /* 571 ** wakeup anyone in WOPEN 572 */ 573 if (PortP->State & (PORT_ISOPEN | RIO_WOPEN) ) 574 wake_up_interruptible (&PortP->gs.open_wait); 575#ifdef STATS 576 PortP->Stat.ModemOnCnt++; 577#endif 578 } 579 } else { 580 /* 581 ** Has carrier just dropped? 582 */ 583 if (PortP->State & RIO_CARR_ON) { 584 if (PortP->State & (PORT_ISOPEN|RIO_WOPEN|RIO_MOPEN)) 585 tty_hangup (PortP->gs.tty); 586 PortP->State &= ~RIO_CARR_ON; 587 rio_dprintk (RIO_DEBUG_CMD, "Carrirer just went down\n"); 588#ifdef STATS 589 PortP->Stat.ModemOffCnt++; 590#endif 591 } 592 } 593 } 594 } 595#endif 596 } 597 break; 598 599 default: 600 rio_dprintk (RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %d\n", 601 RBYTE(PktCmdP->Command),HostP-p->RIOHosts); 602 break; 603 } 604 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 605 606 func_exit (); 607 608 return TRUE; 609} 610/* 611** The command mechanism: 612** Each rup has a chain of commands associated with it. 613** This chain is maintained by routines in this file. 614** Periodically we are called and we run a quick check of all the 615** active chains to determine if there is a command to be executed, 616** and if the rup is ready to accept it. 617** 618*/ 619 620/* 621** Allocate an empty command block. 622*/ 623struct CmdBlk * 624RIOGetCmdBlk() 625{ 626 struct CmdBlk *CmdBlkP; 627 628 CmdBlkP = (struct CmdBlk *)sysbrk(sizeof(struct CmdBlk)); 629 if (CmdBlkP) 630 bzero(CmdBlkP, sizeof(struct CmdBlk)); 631 632 return CmdBlkP; 633} 634 635/* 636** Return a block to the head of the free list. 637*/ 638void 639RIOFreeCmdBlk(CmdBlkP) 640struct CmdBlk *CmdBlkP; 641{ 642 sysfree((void *)CmdBlkP, sizeof(struct CmdBlk)); 643} 644 645/* 646** attach a command block to the list of commands to be performed for 647** a given rup. 648*/ 649int 650RIOQueueCmdBlk(HostP, Rup, CmdBlkP) 651struct Host *HostP; 652uint Rup; 653struct CmdBlk *CmdBlkP; 654{ 655 struct CmdBlk **Base; 656 struct UnixRup *UnixRupP; 657 unsigned long flags; 658 659#ifdef CHECK 660 CheckHostP( HostP ); 661 CheckRup( Rup ); 662 CheckCmdBlkP( CmdBlkP ); 663#endif 664 if ( Rup >= (ushort)(MAX_RUP+LINKS_PER_UNIT) ) { 665 rio_dprintk (RIO_DEBUG_CMD, "Illegal rup number %d in RIOQueueCmdBlk\n",Rup); 666 RIOFreeCmdBlk( CmdBlkP ); 667 return RIO_FAIL; 668 } 669 670 UnixRupP = &HostP->UnixRups[Rup]; 671 672 rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); 673 674 /* 675 ** If the RUP is currently inactive, then put the request 676 ** straight on the RUP.... 677 */ 678 if ( (UnixRupP->CmdsWaitingP == NULL) && (UnixRupP->CmdPendingP == NULL) && 679 (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE ) && 680 (CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP)(CmdBlkP->PreArg,CmdBlkP) 681 :TRUE)) { 682 rio_dprintk (RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%x\n", 683 CmdBlkP->Packet.data[0]); 684 685 686 /* 687 ** Whammy! blat that pack! 688 */ 689 HostP->Copy( (caddr_t)&CmdBlkP->Packet, 690 RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt ), sizeof(PKT) ); 691 692 /* 693 ** place command packet on the pending position. 694 */ 695 UnixRupP->CmdPendingP = CmdBlkP; 696 697 /* 698 ** set the command register 699 */ 700 WWORD(UnixRupP->RupP->txcontrol , TX_PACKET_READY); 701 702 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); 703 704 return RIO_SUCCESS; 705 } 706 rio_dprintk (RIO_DEBUG_CMD, "RUP active - en-queing\n"); 707 708 if ( UnixRupP->CmdsWaitingP != NULL) 709 rio_dprintk (RIO_DEBUG_CMD, "Rup active - command waiting\n"); 710 if ( UnixRupP->CmdPendingP != NULL ) 711 rio_dprintk (RIO_DEBUG_CMD, "Rup active - command pending\n"); 712 if ( RWORD(UnixRupP->RupP->txcontrol) != TX_RUP_INACTIVE ) 713 rio_dprintk (RIO_DEBUG_CMD, "Rup active - command rup not ready\n"); 714 715 Base = &UnixRupP->CmdsWaitingP; 716 717 rio_dprintk (RIO_DEBUG_CMD, "First try to queue cmdblk 0x%x at 0x%x\n", (int)CmdBlkP,(int)Base); 718 719 while ( *Base ) { 720 rio_dprintk (RIO_DEBUG_CMD, "Command cmdblk 0x%x here\n", (int)(*Base)); 721 Base = &((*Base)->NextP); 722 rio_dprintk (RIO_DEBUG_CMD, "Now try to queue cmd cmdblk 0x%x at 0x%x\n", 723 (int)CmdBlkP,(int)Base); 724 } 725 726 rio_dprintk (RIO_DEBUG_CMD, "Will queue cmdblk 0x%x at 0x%x\n",(int)CmdBlkP,(int)Base); 727 728 *Base = CmdBlkP; 729 730 CmdBlkP->NextP = NULL; 731 732 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); 733 734 return RIO_SUCCESS; 735} 736 737/* 738** Here we go - if there is an empty rup, fill it! 739** must be called at splrio() or higher. 740*/ 741void 742RIOPollHostCommands(p, HostP) 743struct rio_info * p; 744struct Host * HostP; 745{ 746 register struct CmdBlk *CmdBlkP; 747 register struct UnixRup *UnixRupP; 748 struct PKT *PacketP; 749 ushort Rup; 750 unsigned long flags; 751 752 753 Rup = MAX_RUP+LINKS_PER_UNIT; 754 755 do { /* do this loop for each RUP */ 756 /* 757 ** locate the rup we are processing & lock it 758 */ 759 UnixRupP = &HostP->UnixRups[--Rup]; 760 761 spin_lock_irqsave(&UnixRupP->RupLock, flags); 762 763 /* 764 ** First check for incoming commands: 765 */ 766 if ( RWORD(UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE ) { 767 int FreeMe; 768 769 PacketP =(PKT *)RIO_PTR(HostP->Caddr,RWORD(UnixRupP->RupP->rxpkt)); 770 771 ShowPacket( DBG_CMD, PacketP ); 772 773 switch ( RBYTE(PacketP->dest_port) ) { 774 case BOOT_RUP: 775 rio_dprintk (RIO_DEBUG_CMD, "Incoming Boot %s packet '%x'\n", 776 RBYTE(PacketP->len) & 0x80 ? "Command":"Data", 777 RBYTE(PacketP->data[0])); 778 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); 779 FreeMe= RIOBootRup(p, Rup,HostP,PacketP); 780 rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); 781 break; 782 783 case COMMAND_RUP: 784 /* 785 ** Free the RUP lock as loss of carrier causes a 786 ** ttyflush which will (eventually) call another 787 ** routine that uses the RUP lock. 788 */ 789 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); 790 FreeMe= RIOCommandRup(p, Rup,HostP,PacketP); 791 if (PacketP->data[5] == MEMDUMP) { 792 rio_dprintk (RIO_DEBUG_CMD, "Memdump from 0x%x complete\n", 793 *(ushort *) &(PacketP->data[6])); 794 HostP->Copy( (caddr_t)&(PacketP->data[8]), 795 (caddr_t)p->RIOMemDump, 32 ); 796 } 797 rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); 798 break; 799 800 case ROUTE_RUP: 801 rio_spin_unlock_irqrestore( &UnixRupP->RupLock, flags); 802 FreeMe = RIORouteRup(p, Rup, HostP, PacketP ); 803 rio_spin_lock_irqsave( &UnixRupP->RupLock, flags ); 804 break; 805 806 default: 807 rio_dprintk (RIO_DEBUG_CMD, "Unknown RUP %d\n", RBYTE(PacketP->dest_port)); 808 FreeMe = 1; 809 break; 810 } 811 812 if ( FreeMe ) { 813 rio_dprintk (RIO_DEBUG_CMD, "Free processed incoming command packet\n"); 814 put_free_end(HostP,PacketP); 815 816 WWORD(UnixRupP->RupP->rxcontrol , RX_RUP_INACTIVE); 817 818 if ( RWORD(UnixRupP->RupP->handshake)==PHB_HANDSHAKE_SET ) { 819 rio_dprintk (RIO_DEBUG_CMD, "Handshake rup %d\n",Rup); 820 WWORD(UnixRupP->RupP->handshake, 821 PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET); 822 } 823 } 824 } 825 826 /* 827 ** IF a command was running on the port, 828 ** and it has completed, then tidy it up. 829 */ 830 if ( (CmdBlkP = UnixRupP->CmdPendingP) && /* ASSIGN! */ 831 (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) { 832 /* 833 ** we are idle. 834 ** there is a command in pending. 835 ** Therefore, this command has finished. 836 ** So, wakeup whoever is waiting for it (and tell them 837 ** what happened). 838 */ 839 if ( CmdBlkP->Packet.dest_port == BOOT_RUP ) 840 rio_dprintk (RIO_DEBUG_CMD, "Free Boot %s Command Block '%x'\n", 841 CmdBlkP->Packet.len & 0x80 ? "Command":"Data", 842 CmdBlkP->Packet.data[0]); 843 844 rio_dprintk (RIO_DEBUG_CMD, "Command 0x%x completed\n",(int)CmdBlkP); 845 846 /* 847 ** Clear the Rup lock to prevent mutual exclusion. 848 */ 849 if ( CmdBlkP->PostFuncP ) { 850 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); 851 (*CmdBlkP->PostFuncP) (CmdBlkP->PostArg,CmdBlkP); 852 rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); 853 } 854 855 /* 856 ** ....clear the pending flag.... 857 */ 858 UnixRupP->CmdPendingP = NULL; 859 860 /* 861 ** ....and return the command block to the freelist. 862 */ 863 RIOFreeCmdBlk( CmdBlkP ); 864 } 865 866 /* 867 ** If there is a command for this rup, and the rup 868 ** is idle, then process the command 869 */ 870 if ( (CmdBlkP = UnixRupP->CmdsWaitingP) && /* ASSIGN! */ 871 (UnixRupP->CmdPendingP == NULL) && 872 (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) { 873 /* 874 ** if the pre-function is non-zero, call it. 875 ** If it returns RIO_FAIL then don't 876 ** send this command yet! 877 */ 878#ifdef CHECK 879 CheckCmdBlkP (CmdBlkP); 880#endif 881 if ( !(CmdBlkP->PreFuncP ? 882 (*CmdBlkP->PreFuncP)(CmdBlkP->PreArg, CmdBlkP) : TRUE)) { 883 rio_dprintk (RIO_DEBUG_CMD, "Not ready to start command 0x%x\n",(int)CmdBlkP); 884 } 885 else { 886 rio_dprintk (RIO_DEBUG_CMD, "Start new command 0x%x Cmd byte is 0x%x\n", 887 (int)CmdBlkP, CmdBlkP->Packet.data[0]); 888 /* 889 ** Whammy! blat that pack! 890 */ 891#ifdef CHECK 892 CheckPacketP ((PKT *)RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt)); 893#endif 894 HostP->Copy( (caddr_t)&CmdBlkP->Packet, 895 RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt), sizeof(PKT)); 896 897 /* 898 ** remove the command from the rup command queue... 899 */ 900 UnixRupP->CmdsWaitingP = CmdBlkP->NextP; 901 902 /* 903 ** ...and place it on the pending position. 904 */ 905 UnixRupP->CmdPendingP = CmdBlkP; 906 907 /* 908 ** set the command register 909 */ 910 WWORD(UnixRupP->RupP->txcontrol,TX_PACKET_READY); 911 912 /* 913 ** the command block will be freed 914 ** when the command has been processed. 915 */ 916 } 917 } 918 spin_unlock_irqrestore(&UnixRupP->RupLock, flags); 919 } while ( Rup ); 920} 921 922 923/* 924** Return the length of the named string 925*/ 926int 927RIOStrlen(Str) 928register char *Str; 929{ 930 register int len = 0; 931 932 while ( *Str++ ) 933 len++; 934 return len; 935} 936 937/* 938** compares s1 to s2 and return 0 if they match. 939*/ 940int 941RIOStrCmp(s1, s2) 942register char *s1; 943register char *s2; 944{ 945 while ( *s1 && *s2 && *s1==*s2 ) 946 s1++, s2++; 947 return *s1-*s2; 948} 949 950/* 951** compares s1 to s2 for upto n bytes and return 0 if they match. 952*/ 953int 954RIOStrnCmp(s1, s2, n) 955register char *s1; 956register char *s2; 957int n; 958{ 959 while ( n && *s1 && *s2 && *s1==*s2 ) 960 n--, s1++, s2++; 961 return n ? *s1!=*s2 : 0; 962} 963 964/* 965** copy up to 'len' bytes from 'from' to 'to'. 966*/ 967void 968RIOStrNCpy(to, from, len) 969char *to; 970char *from; 971int len; 972{ 973 while ( len-- && (*to++ = *from++) ) 974 ; 975 to[-1]='\0'; 976} 977 978int 979RIOWFlushMark(iPortP, CmdBlkP) 980int iPortP; 981struct CmdBlk *CmdBlkP; 982{ 983 struct Port * PortP = (struct Port *)iPortP; 984 unsigned long flags; 985 986 rio_spin_lock_irqsave(&PortP->portSem, flags); 987#ifdef CHECK 988 CheckPortP( PortP ); 989#endif 990 PortP->WflushFlag++; 991 PortP->MagicFlags |= MAGIC_FLUSH; 992 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 993 return RIOUnUse( iPortP, CmdBlkP ); 994} 995 996int 997RIORFlushEnable(iPortP, CmdBlkP) 998int iPortP; 999struct CmdBlk *CmdBlkP; 1000{ 1001 struct Port * PortP = (struct Port *)iPortP; 1002 PKT *PacketP; 1003 unsigned long flags; 1004 1005 rio_spin_lock_irqsave(&PortP->portSem, flags); 1006 1007 while ( can_remove_receive(&PacketP, PortP) ) { 1008 remove_receive(PortP); 1009 ShowPacket(DBG_PROC, PacketP ); 1010 put_free_end( PortP->HostP, PacketP ); 1011 } 1012 1013 if ( RWORD(PortP->PhbP->handshake)==PHB_HANDSHAKE_SET ) { 1014 /* 1015 ** MAGIC! (Basically, handshake the RX buffer, so that 1016 ** the RTAs upstream can be re-enabled.) 1017 */ 1018 rio_dprintk (RIO_DEBUG_CMD, "Util: Set RX handshake bit\n"); 1019 WWORD(PortP->PhbP->handshake, PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET); 1020 } 1021 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 1022 return RIOUnUse( iPortP, CmdBlkP ); 1023} 1024 1025int 1026RIOUnUse(iPortP, CmdBlkP) 1027int iPortP; 1028struct CmdBlk *CmdBlkP; 1029{ 1030 struct Port * PortP = (struct Port *)iPortP; 1031 unsigned long flags; 1032 1033 rio_spin_lock_irqsave(&PortP->portSem, flags); 1034 1035#ifdef CHECK 1036 CheckPortP( PortP ); 1037#endif 1038 rio_dprintk (RIO_DEBUG_CMD, "Decrement in use count for port\n"); 1039 1040 if (PortP->InUse) { 1041 if ( --PortP->InUse != NOT_INUSE ) { 1042 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 1043 return 0; 1044 } 1045 } 1046 /* 1047 ** While PortP->InUse is set (i.e. a preemptive command has been sent to 1048 ** the RTA and is awaiting completion), any transmit data is prevented from 1049 ** being transferred from the write queue into the transmit packets 1050 ** (add_transmit) and no furthur transmit interrupt will be sent for that 1051 ** data. The next interrupt will occur up to 500ms later (RIOIntr is called 1052 ** twice a second as a saftey measure). This was the case when kermit was 1053 ** used to send data into a RIO port. After each packet was sent, TCFLSH 1054 ** was called to flush the read queue preemptively. PortP->InUse was 1055 ** incremented, thereby blocking the 6 byte acknowledgement packet 1056 ** transmitted back. This acknowledgment hung around for 500ms before 1057 ** being sent, thus reducing input performance substantially!. 1058 ** When PortP->InUse becomes NOT_INUSE, we must ensure that any data 1059 ** hanging around in the transmit buffer is sent immediately. 1060 */ 1061 WWORD(PortP->HostP->ParmMapP->tx_intr, 1); 1062 /* What to do here .. 1063 wakeup( (caddr_t)&(PortP->InUse) ); 1064 */ 1065 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 1066 return 0; 1067} 1068 1069void 1070ShowPacket(Flags, PacketP) 1071uint Flags; 1072struct PKT *PacketP; 1073{ 1074} 1075 1076/* 1077** 1078** How to use this file: 1079** 1080** To send a command down a rup, you need to allocate a command block, fill 1081** in the packet information, fill in the command number, fill in the pre- 1082** and post- functions and arguments, and then add the command block to the 1083** queue of command blocks for the port in question. When the port is idle, 1084** then the pre-function will be called. If this returns RIO_FAIL then the 1085** command will be re-queued and tried again at a later date (probably in one 1086** clock tick). If the pre-function returns NOT RIO_FAIL, then the command 1087** packet will be queued on the RUP, and the txcontrol field set to the 1088** command number. When the txcontrol field has changed from being the 1089** command number, then the post-function will be called, with the argument 1090** specified earlier, a pointer to the command block, and the value of 1091** txcontrol. 1092** 1093** To allocate a command block, call RIOGetCmdBlk(). This returns a pointer 1094** to the command block structure allocated, or NULL if there aren't any. 1095** The block will have been zeroed for you. 1096** 1097** The structure has the following fields: 1098** 1099** struct CmdBlk 1100** { 1101** struct CmdBlk *NextP; ** Pointer to next command block ** 1102** struct PKT Packet; ** A packet, to copy to the rup ** 1103** int (*PreFuncP)(); ** The func to call to check if OK ** 1104** int PreArg; ** The arg for the func ** 1105** int (*PostFuncP)(); ** The func to call when completed ** 1106** int PostArg; ** The arg for the func ** 1107** }; 1108** 1109** You need to fill in ALL fields EXCEPT NextP, which is used to link the 1110** blocks together either on the free list or on the Rup list. 1111** 1112** Packet is an actual packet structure to be filled in with the packet 1113** information associated with the command. You need to fill in everything, 1114** as the command processore doesn't process the command packet in any way. 1115** 1116** The PreFuncP is called before the packet is enqueued on the host rup. 1117** PreFuncP is called as (*PreFuncP)(PreArg, CmdBlkP);. PreFuncP must 1118** return !RIO_FAIL to have the packet queued on the rup, and RIO_FAIL 1119** if the packet is NOT to be queued. 1120** 1121** The PostFuncP is called when the command has completed. It is called 1122** as (*PostFuncP)(PostArg, CmdBlkP, txcontrol);. PostFuncP is not expected 1123** to return a value. PostFuncP does NOT need to free the command block, 1124** as this happens automatically after PostFuncP returns. 1125** 1126** Once the command block has been filled in, it is attached to the correct 1127** queue by calling RIOQueueCmdBlk( HostP, Rup, CmdBlkP ) where HostP is 1128** a pointer to the struct Host, Rup is the NUMBER of the rup (NOT a pointer 1129** to it!), and CmdBlkP is the pointer to the command block allocated using 1130** RIOGetCmdBlk(). 1131** 1132*/ 1133