Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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