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 : rioboot.c 24** SID : 1.3 25** Last Modified : 11/6/98 10:33:36 26** Retrieved : 11/6/98 10:33:48 27** 28** ident @(#)rioboot.c 1.3 29** 30** ----------------------------------------------------------------------------- 31*/ 32 33#ifdef SCCS_LABELS 34static char *_rioboot_c_sccs_ = "@(#)rioboot.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/interrupt.h> 42#include <asm/io.h> 43#include <asm/system.h> 44#include <asm/string.h> 45#include <asm/semaphore.h> 46 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 56#include "linux_compat.h" 57#include "rio_linux.h" 58#include "typdef.h" 59#include "pkt.h" 60#include "daemon.h" 61#include "rio.h" 62#include "riospace.h" 63#include "top.h" 64#include "cmdpkt.h" 65#include "map.h" 66#include "riotypes.h" 67#include "rup.h" 68#include "port.h" 69#include "riodrvr.h" 70#include "rioinfo.h" 71#include "func.h" 72#include "errors.h" 73#include "pci.h" 74 75#include "parmmap.h" 76#include "unixrup.h" 77#include "board.h" 78#include "host.h" 79#include "error.h" 80#include "phb.h" 81#include "link.h" 82#include "cmdblk.h" 83#include "route.h" 84 85static uchar 86RIOAtVec2Ctrl[] = 87{ 88 /* 0 */ INTERRUPT_DISABLE, 89 /* 1 */ INTERRUPT_DISABLE, 90 /* 2 */ INTERRUPT_DISABLE, 91 /* 3 */ INTERRUPT_DISABLE, 92 /* 4 */ INTERRUPT_DISABLE, 93 /* 5 */ INTERRUPT_DISABLE, 94 /* 6 */ INTERRUPT_DISABLE, 95 /* 7 */ INTERRUPT_DISABLE, 96 /* 8 */ INTERRUPT_DISABLE, 97 /* 9 */ IRQ_9|INTERRUPT_ENABLE, 98 /* 10 */ INTERRUPT_DISABLE, 99 /* 11 */ IRQ_11|INTERRUPT_ENABLE, 100 /* 12 */ IRQ_12|INTERRUPT_ENABLE, 101 /* 13 */ INTERRUPT_DISABLE, 102 /* 14 */ INTERRUPT_DISABLE, 103 /* 15 */ IRQ_15|INTERRUPT_ENABLE 104}; 105 106/* 107** Load in the RTA boot code. 108*/ 109int 110RIOBootCodeRTA(p, rbp) 111struct rio_info * p; 112struct DownLoad * rbp; 113{ 114 int offset; 115 116 func_enter (); 117 118 /* Linux doesn't allow you to disable interrupts during a 119 "copyin". (Crash when a pagefault occurs). */ 120 /* disable(oldspl); */ 121 122 rio_dprintk (RIO_DEBUG_BOOT, "Data at user address 0x%x\n",(int)rbp->DataP); 123 124 /* 125 ** Check that we have set asside enough memory for this 126 */ 127 if ( rbp->Count > SIXTY_FOUR_K ) { 128 rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot Code Too Large!\n"); 129 p->RIOError.Error = HOST_FILE_TOO_LARGE; 130 /* restore(oldspl); */ 131 func_exit (); 132 return ENOMEM; 133 } 134 135 if ( p->RIOBooting ) { 136 rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot Code : BUSY BUSY BUSY!\n"); 137 p->RIOError.Error = BOOT_IN_PROGRESS; 138 /* restore(oldspl); */ 139 func_exit (); 140 return EBUSY; 141 } 142 143 /* 144 ** The data we load in must end on a (RTA_BOOT_DATA_SIZE) byte boundary, 145 ** so calculate how far we have to move the data up the buffer 146 ** to achieve this. 147 */ 148 offset = (RTA_BOOT_DATA_SIZE - (rbp->Count % RTA_BOOT_DATA_SIZE)) % 149 RTA_BOOT_DATA_SIZE; 150 151 /* 152 ** Be clean, and clear the 'unused' portion of the boot buffer, 153 ** because it will (eventually) be part of the Rta run time environment 154 ** and so should be zeroed. 155 */ 156 bzero( (caddr_t)p->RIOBootPackets, offset ); 157 158 /* 159 ** Copy the data from user space. 160 */ 161 162 if ( copyin((int)rbp->DataP,((caddr_t)(p->RIOBootPackets))+offset, 163 rbp->Count) ==COPYFAIL ) { 164 rio_dprintk (RIO_DEBUG_BOOT, "Bad data copy from user space\n"); 165 p->RIOError.Error = COPYIN_FAILED; 166 /* restore(oldspl); */ 167 func_exit (); 168 return EFAULT; 169 } 170 171 /* 172 ** Make sure that our copy of the size includes that offset we discussed 173 ** earlier. 174 */ 175 p->RIONumBootPkts = (rbp->Count+offset)/RTA_BOOT_DATA_SIZE; 176 p->RIOBootCount = rbp->Count; 177 178 /* restore(oldspl); */ 179 func_exit(); 180 return 0; 181} 182 183void rio_start_card_running (struct Host * HostP) 184{ 185 func_enter (); 186 187 switch ( HostP->Type ) { 188 case RIO_AT: 189 rio_dprintk (RIO_DEBUG_BOOT, "Start ISA card running\n"); 190 WBYTE(HostP->Control, 191 BOOT_FROM_RAM | EXTERNAL_BUS_ON 192 | HostP->Mode 193 | RIOAtVec2Ctrl[HostP->Ivec & 0xF] ); 194 break; 195 196#ifdef FUTURE_RELEASE 197 case RIO_MCA: 198 /* 199 ** MCA handles IRQ vectors differently, so we don't write 200 ** them to this register. 201 */ 202 rio_dprintk (RIO_DEBUG_BOOT, "Start MCA card running\n"); 203 WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode); 204 break; 205 206 case RIO_EISA: 207 /* 208 ** EISA is totally different and expects OUTBZs to turn it on. 209 */ 210 rio_dprintk (RIO_DEBUG_BOOT, "Start EISA card running\n"); 211 OUTBZ( HostP->Slot, EISA_CONTROL_PORT, HostP->Mode | RIOEisaVec2Ctrl[HostP->Ivec] | EISA_TP_RUN | EISA_TP_BUS_ENABLE | EISA_TP_BOOT_FROM_RAM ); 212 break; 213#endif 214 215 case RIO_PCI: 216 /* 217 ** PCI is much the same as MCA. Everything is once again memory 218 ** mapped, so we are writing to memory registers instead of io 219 ** ports. 220 */ 221 rio_dprintk (RIO_DEBUG_BOOT, "Start PCI card running\n"); 222 WBYTE(HostP->Control, PCITpBootFromRam | PCITpBusEnable | HostP->Mode); 223 break; 224 default: 225 rio_dprintk (RIO_DEBUG_BOOT, "Unknown host type %d\n", HostP->Type); 226 break; 227 } 228/* 229 printk (KERN_INFO "Done with starting the card\n"); 230 func_exit (); 231*/ 232 return; 233} 234 235/* 236** Load in the host boot code - load it directly onto all halted hosts 237** of the correct type. 238** 239** Put your rubber pants on before messing with this code - even the magic 240** numbers have trouble understanding what they are doing here. 241*/ 242int 243RIOBootCodeHOST(p, rbp) 244struct rio_info * p; 245register struct DownLoad *rbp; 246{ 247 register struct Host *HostP; 248 register caddr_t Cad; 249 register PARM_MAP *ParmMapP; 250 register int RupN; 251 int PortN; 252 uint host; 253 caddr_t StartP; 254 BYTE *DestP; 255 int wait_count; 256 ushort OldParmMap; 257 ushort offset; /* It is very important that this is a ushort */ 258 /* uint byte; */ 259 caddr_t DownCode = NULL; 260 unsigned long flags; 261 262 HostP = NULL; /* Assure the compiler we've initialized it */ 263 for ( host=0; host<p->RIONumHosts; host++ ) { 264 rio_dprintk (RIO_DEBUG_BOOT, "Attempt to boot host %d\n",host); 265 HostP = &p->RIOHosts[host]; 266 267 rio_dprintk (RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", 268 HostP->Type, HostP->Mode, HostP->Ivec); 269 270 271 if ( (HostP->Flags & RUN_STATE) != RC_WAITING ) { 272 rio_dprintk (RIO_DEBUG_BOOT, "%s %d already running\n","Host",host); 273 continue; 274 } 275 276 /* 277 ** Grab a 32 bit pointer to the card. 278 */ 279 Cad = HostP->Caddr; 280 281 /* 282 ** We are going to (try) and load in rbp->Count bytes. 283 ** The last byte will reside at p->RIOConf.HostLoadBase-1; 284 ** Therefore, we need to start copying at address 285 ** (caddr+p->RIOConf.HostLoadBase-rbp->Count) 286 */ 287 StartP = (caddr_t)&Cad[p->RIOConf.HostLoadBase-rbp->Count]; 288 289 rio_dprintk (RIO_DEBUG_BOOT, "kernel virtual address for host is 0x%x\n", (int)Cad ); 290 rio_dprintk (RIO_DEBUG_BOOT, "kernel virtual address for download is 0x%x\n", (int)StartP); 291 rio_dprintk (RIO_DEBUG_BOOT, "host loadbase is 0x%x\n",p->RIOConf.HostLoadBase); 292 rio_dprintk (RIO_DEBUG_BOOT, "size of download is 0x%x\n", rbp->Count); 293 294 if ( p->RIOConf.HostLoadBase < rbp->Count ) { 295 rio_dprintk (RIO_DEBUG_BOOT, "Bin too large\n"); 296 p->RIOError.Error = HOST_FILE_TOO_LARGE; 297 func_exit (); 298 return EFBIG; 299 } 300 /* 301 ** Ensure that the host really is stopped. 302 ** Disable it's external bus & twang its reset line. 303 */ 304 RIOHostReset( HostP->Type, (struct DpRam *)HostP->CardP, HostP->Slot ); 305 306 /* 307 ** Copy the data directly from user space to the SRAM. 308 ** This ain't going to be none too clever if the download 309 ** code is bigger than this segment. 310 */ 311 rio_dprintk (RIO_DEBUG_BOOT, "Copy in code\n"); 312 313 /* 314 ** PCI hostcard can't cope with 32 bit accesses and so need to copy 315 ** data to a local buffer, and then dripfeed the card. 316 */ 317 if ( HostP->Type == RIO_PCI ) { 318 /* int offset; */ 319 320 DownCode = sysbrk(rbp->Count); 321 if ( !DownCode ) { 322 rio_dprintk (RIO_DEBUG_BOOT, "No system memory available\n"); 323 p->RIOError.Error = NOT_ENOUGH_CORE_FOR_PCI_COPY; 324 func_exit (); 325 return ENOMEM; 326 } 327 bzero(DownCode, rbp->Count); 328 329 if ( copyin((int)rbp->DataP,DownCode,rbp->Count)==COPYFAIL ) { 330 rio_dprintk (RIO_DEBUG_BOOT, "Bad copyin of host data\n"); 331 p->RIOError.Error = COPYIN_FAILED; 332 func_exit (); 333 return EFAULT; 334 } 335 336 HostP->Copy( DownCode, StartP, rbp->Count ); 337 338 sysfree( DownCode, rbp->Count ); 339 } 340 else if ( copyin((int)rbp->DataP,StartP,rbp->Count)==COPYFAIL ) { 341 rio_dprintk (RIO_DEBUG_BOOT, "Bad copyin of host data\n"); 342 p->RIOError.Error = COPYIN_FAILED; 343 func_exit (); 344 return EFAULT; 345 } 346 347 rio_dprintk (RIO_DEBUG_BOOT, "Copy completed\n"); 348 349 /* 350 ** S T O P ! 351 ** 352 ** Upto this point the code has been fairly rational, and possibly 353 ** even straight forward. What follows is a pile of crud that will 354 ** magically turn into six bytes of transputer assembler. Normally 355 ** you would expect an array or something, but, being me, I have 356 ** chosen [been told] to use a technique whereby the startup code 357 ** will be correct if we change the loadbase for the code. Which 358 ** brings us onto another issue - the loadbase is the *end* of the 359 ** code, not the start. 360 ** 361 ** If I were you I wouldn't start from here. 362 */ 363 364 /* 365 ** We now need to insert a short boot section into 366 ** the memory at the end of Sram2. This is normally (de)composed 367 ** of the last eight bytes of the download code. The 368 ** download has been assembled/compiled to expect to be 369 ** loaded from 0x7FFF downwards. We have loaded it 370 ** at some other address. The startup code goes into the small 371 ** ram window at Sram2, in the last 8 bytes, which are really 372 ** at addresses 0x7FF8-0x7FFF. 373 ** 374 ** If the loadbase is, say, 0x7C00, then we need to branch to 375 ** address 0x7BFE to run the host.bin startup code. We assemble 376 ** this jump manually. 377 ** 378 ** The two byte sequence 60 08 is loaded into memory at address 379 ** 0x7FFE,F. This is a local branch to location 0x7FF8 (60 is nfix 0, 380 ** which adds '0' to the .O register, complements .O, and then shifts 381 ** it left by 4 bit positions, 08 is a jump .O+8 instruction. This will 382 ** add 8 to .O (which was 0xFFF0), and will branch RELATIVE to the new 383 ** location. Now, the branch starts from the value of .PC (or .IP or 384 ** whatever the bloody register is called on this chip), and the .PC 385 ** will be pointing to the location AFTER the branch, in this case 386 ** .PC == 0x8000, so the branch will be to 0x8000+0xFFF8 = 0x7FF8. 387 ** 388 ** A long branch is coded at 0x7FF8. This consists of loading a four 389 ** byte offset into .O using nfix (as above) and pfix operators. The 390 ** pfix operates in exactly the same way as the nfix operator, but 391 ** without the complement operation. The offset, of course, must be 392 ** relative to the address of the byte AFTER the branch instruction, 393 ** which will be (urm) 0x7FFC, so, our final destination of the branch 394 ** (loadbase-2), has to be reached from here. Imagine that the loadbase 395 ** is 0x7C00 (which it is), then we will need to branch to 0x7BFE (which 396 ** is the first byte of the initial two byte short local branch of the 397 ** download code). 398 ** 399 ** To code a jump from 0x7FFC (which is where the branch will start 400 ** from) to 0x7BFE, we will need to branch 0xFC02 bytes (0x7FFC+0xFC02)= 401 ** 0x7BFE. 402 ** This will be coded as four bytes: 403 ** 60 2C 20 02 404 ** being nfix .O+0 405 ** pfix .O+C 406 ** pfix .O+0 407 ** jump .O+2 408 ** 409 ** The nfix operator is used, so that the startup code will be 410 ** compatible with the whole Tp family. (lies, damn lies, it'll never 411 ** work in a month of Sundays). 412 ** 413 ** The nfix nyble is the 1s compliment of the nyble value you 414 ** want to load - in this case we wanted 'F' so we nfix loaded '0'. 415 */ 416 417 418 /* 419 ** Dest points to the top 8 bytes of Sram2. The Tp jumps 420 ** to 0x7FFE at reset time, and starts executing. This is 421 ** a short branch to 0x7FF8, where a long branch is coded. 422 */ 423 424 DestP = (BYTE *)&Cad[0x7FF8]; /* <<<---- READ THE ABOVE COMMENTS */ 425 426#define NFIX(N) (0x60 | (N)) /* .O = (~(.O + N))<<4 */ 427#define PFIX(N) (0x20 | (N)) /* .O = (.O + N)<<4 */ 428#define JUMP(N) (0x00 | (N)) /* .PC = .PC + .O */ 429 430 /* 431 ** 0x7FFC is the address of the location following the last byte of 432 ** the four byte jump instruction. 433 ** READ THE ABOVE COMMENTS 434 ** 435 ** offset is (TO-FROM) % MEMSIZE, but with compound buggering about. 436 ** Memsize is 64K for this range of Tp, so offset is a short (unsigned, 437 ** cos I don't understand 2's complement). 438 */ 439 offset = (p->RIOConf.HostLoadBase-2)-0x7FFC; 440 WBYTE( DestP[0] , NFIX(((ushort)(~offset) >> (ushort)12) & 0xF) ); 441 WBYTE( DestP[1] , PFIX(( offset >> 8) & 0xF) ); 442 WBYTE( DestP[2] , PFIX(( offset >> 4) & 0xF) ); 443 WBYTE( DestP[3] , JUMP( offset & 0xF) ); 444 445 WBYTE( DestP[6] , NFIX(0) ); 446 WBYTE( DestP[7] , JUMP(8) ); 447 448 rio_dprintk (RIO_DEBUG_BOOT, "host loadbase is 0x%x\n",p->RIOConf.HostLoadBase); 449 rio_dprintk (RIO_DEBUG_BOOT, "startup offset is 0x%x\n",offset); 450 451 /* 452 ** Flag what is going on 453 */ 454 HostP->Flags &= ~RUN_STATE; 455 HostP->Flags |= RC_STARTUP; 456 457 /* 458 ** Grab a copy of the current ParmMap pointer, so we 459 ** can tell when it has changed. 460 */ 461 OldParmMap = RWORD(HostP->__ParmMapR); 462 463 rio_dprintk (RIO_DEBUG_BOOT, "Original parmmap is 0x%x\n",OldParmMap); 464 465 /* 466 ** And start it running (I hope). 467 ** As there is nothing dodgy or obscure about the 468 ** above code, this is guaranteed to work every time. 469 */ 470 rio_dprintk (RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", 471 HostP->Type, HostP->Mode, HostP->Ivec); 472 473 rio_start_card_running(HostP); 474 475 rio_dprintk (RIO_DEBUG_BOOT, "Set control port\n"); 476 477 /* 478 ** Now, wait for upto five seconds for the Tp to setup the parmmap 479 ** pointer: 480 */ 481 for ( wait_count=0; (wait_count<p->RIOConf.StartupTime)&& 482 (RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) { 483 rio_dprintk (RIO_DEBUG_BOOT, "Checkout %d, 0x%x\n",wait_count,RWORD(HostP->__ParmMapR)); 484 delay(HostP, HUNDRED_MS); 485 486 } 487 488 /* 489 ** If the parmmap pointer is unchanged, then the host code 490 ** has crashed & burned in a really spectacular way 491 */ 492 if ( RWORD(HostP->__ParmMapR) == OldParmMap ) { 493 rio_dprintk (RIO_DEBUG_BOOT, "parmmap 0x%x\n", RWORD(HostP->__ParmMapR)); 494 rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail\n"); 495 496#define HOST_DISABLE \ 497 HostP->Flags &= ~RUN_STATE; \ 498 HostP->Flags |= RC_STUFFED; \ 499 RIOHostReset( HostP->Type, (struct DpRam *)HostP->CardP, HostP->Slot );\ 500 continue 501 502 HOST_DISABLE; 503 } 504 505 rio_dprintk (RIO_DEBUG_BOOT, "Running 0x%x\n", RWORD(HostP->__ParmMapR)); 506 507 /* 508 ** Well, the board thought it was OK, and setup its parmmap 509 ** pointer. For the time being, we will pretend that this 510 ** board is running, and check out what the error flag says. 511 */ 512 513 /* 514 ** Grab a 32 bit pointer to the parmmap structure 515 */ 516 ParmMapP = (PARM_MAP *)RIO_PTR(Cad,RWORD(HostP->__ParmMapR)); 517 rio_dprintk (RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int)ParmMapP); 518 ParmMapP = (PARM_MAP *)((unsigned long)Cad + 519 (unsigned long)((RWORD((HostP->__ParmMapR))) & 0xFFFF)); 520 rio_dprintk (RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int)ParmMapP); 521 522 /* 523 ** The links entry should be 0xFFFF; we set it up 524 ** with a mask to say how many PHBs to use, and 525 ** which links to use. 526 */ 527 if ( (RWORD(ParmMapP->links) & 0xFFFF) != 0xFFFF ) { 528 rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name); 529 rio_dprintk (RIO_DEBUG_BOOT, "Links = 0x%x\n",RWORD(ParmMapP->links)); 530 HOST_DISABLE; 531 } 532 533 WWORD(ParmMapP->links , RIO_LINK_ENABLE); 534 535 rio_dprintk (RIO_DEBUG_BOOT, "Looking for init_done - %d ticks\n",p->RIOConf.StartupTime); 536 HostP->timeout_id = 0; 537 for ( wait_count=0; (wait_count<p->RIOConf.StartupTime) && 538 !RWORD(ParmMapP->init_done); wait_count++ ) { 539 rio_dprintk (RIO_DEBUG_BOOT, "Waiting for init_done\n"); 540 delay(HostP, HUNDRED_MS); 541 } 542 rio_dprintk (RIO_DEBUG_BOOT, "OK! init_done!\n"); 543 544 if (RWORD(ParmMapP->error) != E_NO_ERROR || 545 !RWORD(ParmMapP->init_done) ) { 546 rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name); 547 rio_dprintk (RIO_DEBUG_BOOT, "Timedout waiting for init_done\n"); 548 HOST_DISABLE; 549 } 550 551 rio_dprintk (RIO_DEBUG_BOOT, "Got init_done\n"); 552 553 /* 554 ** It runs! It runs! 555 */ 556 rio_dprintk (RIO_DEBUG_BOOT, "Host ID %x Running\n",HostP->UniqueNum); 557 558 /* 559 ** set the time period between interrupts. 560 */ 561 WWORD(ParmMapP->timer, (short)p->RIOConf.Timer ); 562 563 /* 564 ** Translate all the 16 bit pointers in the __ParmMapR into 565 ** 32 bit pointers for the driver. 566 */ 567 HostP->ParmMapP = ParmMapP; 568 HostP->PhbP = (PHB*)RIO_PTR(Cad,RWORD(ParmMapP->phb_ptr)); 569 HostP->RupP = (RUP*)RIO_PTR(Cad,RWORD(ParmMapP->rups)); 570 HostP->PhbNumP = (ushort*)RIO_PTR(Cad,RWORD(ParmMapP->phb_num_ptr)); 571 HostP->LinkStrP = (LPB*)RIO_PTR(Cad,RWORD(ParmMapP->link_str_ptr)); 572 573 /* 574 ** point the UnixRups at the real Rups 575 */ 576 for ( RupN = 0; RupN<MAX_RUP; RupN++ ) { 577 HostP->UnixRups[RupN].RupP = &HostP->RupP[RupN]; 578 HostP->UnixRups[RupN].Id = RupN+1; 579 HostP->UnixRups[RupN].BaseSysPort = NO_PORT; 580 HostP->UnixRups[RupN].RupLock = SPIN_LOCK_UNLOCKED; 581 } 582 583 for ( RupN = 0; RupN<LINKS_PER_UNIT; RupN++ ) { 584 HostP->UnixRups[RupN+MAX_RUP].RupP = &HostP->LinkStrP[RupN].rup; 585 HostP->UnixRups[RupN+MAX_RUP].Id = 0; 586 HostP->UnixRups[RupN+MAX_RUP].BaseSysPort = NO_PORT; 587 HostP->UnixRups[RupN+MAX_RUP].RupLock = SPIN_LOCK_UNLOCKED; 588 } 589 590 /* 591 ** point the PortP->Phbs at the real Phbs 592 */ 593 for ( PortN=p->RIOFirstPortsMapped; 594 PortN<p->RIOLastPortsMapped+PORTS_PER_RTA; PortN++ ) { 595 if ( p->RIOPortp[PortN]->HostP == HostP ) { 596 struct Port *PortP = p->RIOPortp[PortN]; 597 struct PHB *PhbP; 598 /* int oldspl; */ 599 600 if ( !PortP->Mapped ) 601 continue; 602 603 PhbP = &HostP->PhbP[PortP->HostPort]; 604 rio_spin_lock_irqsave(&PortP->portSem, flags); 605 606 PortP->PhbP = PhbP; 607 608 PortP->TxAdd = (WORD *)RIO_PTR(Cad,RWORD(PhbP->tx_add)); 609 PortP->TxStart = (WORD *)RIO_PTR(Cad,RWORD(PhbP->tx_start)); 610 PortP->TxEnd = (WORD *)RIO_PTR(Cad,RWORD(PhbP->tx_end)); 611 PortP->RxRemove = (WORD *)RIO_PTR(Cad,RWORD(PhbP->rx_remove)); 612 PortP->RxStart = (WORD *)RIO_PTR(Cad,RWORD(PhbP->rx_start)); 613 PortP->RxEnd = (WORD *)RIO_PTR(Cad,RWORD(PhbP->rx_end)); 614 615 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 616 /* 617 ** point the UnixRup at the base SysPort 618 */ 619 if ( !(PortN % PORTS_PER_RTA) ) 620 HostP->UnixRups[PortP->RupNum].BaseSysPort = PortN; 621 } 622 } 623 624 rio_dprintk (RIO_DEBUG_BOOT, "Set the card running... \n"); 625 /* 626 ** last thing - show the world that everything is in place 627 */ 628 HostP->Flags &= ~RUN_STATE; 629 HostP->Flags |= RC_RUNNING; 630 } 631 /* 632 ** MPX always uses a poller. This is actually patched into the system 633 ** configuration and called directly from each clock tick. 634 ** 635 */ 636 p->RIOPolling = 1; 637 638 p->RIOSystemUp++; 639 640 rio_dprintk (RIO_DEBUG_BOOT, "Done everything %x\n", HostP->Ivec); 641 func_exit (); 642 return 0; 643} 644 645 646 647/* 648** Boot an RTA. If we have successfully processed this boot, then 649** return 1. If we havent, then return 0. 650*/ 651int 652RIOBootRup( p, Rup, HostP, PacketP) 653struct rio_info * p; 654uint Rup; 655struct Host *HostP; 656struct PKT *PacketP; 657{ 658 struct PktCmd *PktCmdP = (struct PktCmd *)PacketP->data; 659 struct PktCmd_M *PktReplyP; 660 struct CmdBlk *CmdBlkP; 661 uint sequence; 662 663#ifdef CHECK 664 CheckHost(Host); 665 CheckRup(Rup); 666 CheckHostP(HostP); 667 CheckPacketP(PacketP); 668#endif 669 670 /* 671 ** If we haven't been told what to boot, we can't boot it. 672 */ 673 if ( p->RIONumBootPkts == 0 ) { 674 rio_dprintk (RIO_DEBUG_BOOT, "No RTA code to download yet\n"); 675 return 0; 676 } 677 678 /* rio_dprint(RIO_DEBUG_BOOT, NULL,DBG_BOOT,"Incoming command packet\n"); */ 679 /* ShowPacket( DBG_BOOT, PacketP ); */ 680 681 /* 682 ** Special case of boot completed - if we get one of these then we 683 ** don't need a command block. For all other cases we do, so handle 684 ** this first and then get a command block, then handle every other 685 ** case, relinquishing the command block if disaster strikes! 686 */ 687 if ( (RBYTE(PacketP->len) & PKT_CMD_BIT) && 688 (RBYTE(PktCmdP->Command)==BOOT_COMPLETED) ) 689 return RIOBootComplete(p, HostP, Rup, PktCmdP ); 690 691 /* 692 ** try to unhook a command block from the command free list. 693 */ 694 if ( !(CmdBlkP = RIOGetCmdBlk()) ) { 695 rio_dprintk (RIO_DEBUG_BOOT, "No command blocks to boot RTA! come back later.\n"); 696 return 0; 697 } 698 699 /* 700 ** Fill in the default info on the command block 701 */ 702 CmdBlkP->Packet.dest_unit = Rup < (ushort)MAX_RUP ? Rup : 0; 703 CmdBlkP->Packet.dest_port = BOOT_RUP; 704 CmdBlkP->Packet.src_unit = 0; 705 CmdBlkP->Packet.src_port = BOOT_RUP; 706 707 CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL; 708 PktReplyP = (struct PktCmd_M *)CmdBlkP->Packet.data; 709 710 /* 711 ** process COMMANDS on the boot rup! 712 */ 713 if ( RBYTE(PacketP->len) & PKT_CMD_BIT ) { 714 /* 715 ** We only expect one type of command - a BOOT_REQUEST! 716 */ 717 if ( RBYTE(PktCmdP->Command) != BOOT_REQUEST ) { 718 rio_dprintk (RIO_DEBUG_BOOT, "Unexpected command %d on BOOT RUP %d of host %d\n", 719 PktCmdP->Command,Rup,HostP-p->RIOHosts); 720 ShowPacket( DBG_BOOT, PacketP ); 721 RIOFreeCmdBlk( CmdBlkP ); 722 return 1; 723 } 724 725 /* 726 ** Build a Boot Sequence command block 727 ** 728 ** 02.03.1999 ARG - ESIL 0820 fix 729 ** We no longer need to use "Boot Mode", we'll always allow 730 ** boot requests - the boot will not complete if the device 731 ** appears in the bindings table. 732 ** So, this conditional is not required ... 733 ** 734 if (p->RIOBootMode == RC_BOOT_NONE) 735 ** 736 ** If the system is in slave mode, and a boot request is 737 ** received, set command to BOOT_ABORT so that the boot 738 ** will not complete. 739 ** 740 PktReplyP->Command = BOOT_ABORT; 741 else 742 ** 743 ** We'll just (always) set the command field in packet reply 744 ** to allow an attempted boot sequence : 745 */ 746 PktReplyP->Command = BOOT_SEQUENCE; 747 748 PktReplyP->BootSequence.NumPackets = p->RIONumBootPkts; 749 PktReplyP->BootSequence.LoadBase = p->RIOConf.RtaLoadBase; 750 PktReplyP->BootSequence.CodeSize = p->RIOBootCount; 751 752 CmdBlkP->Packet.len = BOOT_SEQUENCE_LEN | PKT_CMD_BIT; 753 754 bcopy("BOOT",(void *)&CmdBlkP->Packet.data[BOOT_SEQUENCE_LEN],4); 755 756 rio_dprintk (RIO_DEBUG_BOOT, "Boot RTA on Host %d Rup %d - %d (0x%x) packets to 0x%x\n", 757 HostP-p->RIOHosts, Rup, p->RIONumBootPkts, p->RIONumBootPkts, 758 p->RIOConf.RtaLoadBase); 759 760 /* 761 ** If this host is in slave mode, send the RTA an invalid boot 762 ** sequence command block to force it to kill the boot. We wait 763 ** for half a second before sending this packet to prevent the RTA 764 ** attempting to boot too often. The master host should then grab 765 ** the RTA and make it its own. 766 */ 767 p->RIOBooting++; 768 RIOQueueCmdBlk( HostP, Rup, CmdBlkP ); 769 return 1; 770 } 771 772 /* 773 ** It is a request for boot data. 774 */ 775 sequence = RWORD(PktCmdP->Sequence); 776 777 rio_dprintk (RIO_DEBUG_BOOT, "Boot block %d on Host %d Rup%d\n",sequence,HostP-p->RIOHosts,Rup); 778 779 if ( sequence >= p->RIONumBootPkts ) { 780 rio_dprintk (RIO_DEBUG_BOOT, "Got a request for packet %d, max is %d\n", sequence, 781 p->RIONumBootPkts); 782 ShowPacket( DBG_BOOT, PacketP ); 783 } 784 785 PktReplyP->Sequence = sequence; 786 787 bcopy( p->RIOBootPackets[ p->RIONumBootPkts - sequence - 1 ], 788 PktReplyP->BootData, RTA_BOOT_DATA_SIZE ); 789 790 CmdBlkP->Packet.len = PKT_MAX_DATA_LEN; 791 ShowPacket( DBG_BOOT, &CmdBlkP->Packet ); 792 RIOQueueCmdBlk( HostP, Rup, CmdBlkP ); 793 return 1; 794} 795 796/* 797** This function is called when an RTA been booted. 798** If booted by a host, HostP->HostUniqueNum is the booting host. 799** If booted by an RTA, HostP->Mapping[Rup].RtaUniqueNum is the booting RTA. 800** RtaUniq is the booted RTA. 801*/ 802int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct PktCmd *PktCmdP ) 803{ 804 struct Map *MapP = NULL; 805 struct Map *MapP2 = NULL; 806 int Flag; 807 int found; 808 int host, rta; 809 int EmptySlot = -1; 810 int entry, entry2; 811 char *MyType, *MyName; 812 uint MyLink; 813 ushort RtaType; 814 uint RtaUniq = (RBYTE(PktCmdP->UniqNum[0])) + 815 (RBYTE(PktCmdP->UniqNum[1]) << 8) + 816 (RBYTE(PktCmdP->UniqNum[2]) << 16) + 817 (RBYTE(PktCmdP->UniqNum[3]) << 24); 818 819 /* Was RIOBooting-- . That's bad. If an RTA sends two of them, the 820 driver will never think that the RTA has booted... -- REW */ 821 p->RIOBooting = 0; 822 823 rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot completed - BootInProgress now %d\n", p->RIOBooting); 824 825 /* 826 ** Determine type of unit (16/8 port RTA). 827 */ 828 RtaType = GetUnitType(RtaUniq); 829 if ( Rup >= (ushort)MAX_RUP ) { 830 rio_dprintk (RIO_DEBUG_BOOT, "RIO: Host %s has booted an RTA(%d) on link %c\n", 831 HostP->Name, 8 * RtaType, RBYTE(PktCmdP->LinkNum)+'A'); 832 } else { 833 rio_dprintk (RIO_DEBUG_BOOT, "RIO: RTA %s has booted an RTA(%d) on link %c\n", 834 HostP->Mapping[Rup].Name, 8 * RtaType, 835 RBYTE(PktCmdP->LinkNum)+'A'); 836 } 837 838 rio_dprintk (RIO_DEBUG_BOOT, "UniqNum is 0x%x\n",RtaUniq); 839 840 if ( ( RtaUniq == 0x00000000 ) || ( RtaUniq == 0xffffffff ) ) 841 { 842 rio_dprintk (RIO_DEBUG_BOOT, "Illegal RTA Uniq Number\n"); 843 return TRUE; 844 } 845 846 /* 847 ** If this RTA has just booted an RTA which doesn't belong to this 848 ** system, or the system is in slave mode, do not attempt to create 849 ** a new table entry for it. 850 */ 851 if (!RIOBootOk(p, HostP, RtaUniq)) 852 { 853 MyLink = RBYTE(PktCmdP->LinkNum); 854 if (Rup < (ushort) MAX_RUP) 855 { 856 /* 857 ** RtaUniq was clone booted (by this RTA). Instruct this RTA 858 ** to hold off further attempts to boot on this link for 30 859 ** seconds. 860 */ 861 if (RIOSuspendBootRta(HostP, HostP->Mapping[Rup].ID, MyLink)) 862 { 863 rio_dprintk (RIO_DEBUG_BOOT, "RTA failed to suspend booting on link %c\n", 864 'A' + MyLink); 865 } 866 } 867 else 868 { 869 /* 870 ** RtaUniq was booted by this host. Set the booting link 871 ** to hold off for 30 seconds to give another unit a 872 ** chance to boot it. 873 */ 874 WWORD(HostP->LinkStrP[MyLink].WaitNoBoot, 30); 875 } 876 rio_dprintk (RIO_DEBUG_BOOT, "RTA %x not owned - suspend booting down link %c on unit %x\n", 877 RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum); 878 return TRUE; 879 } 880 881 /* 882 ** Check for a SLOT_IN_USE entry for this RTA attached to the 883 ** current host card in the driver table. 884 ** 885 ** If it exists, make a note that we have booted it. Other parts of 886 ** the driver are interested in this information at a later date, 887 ** in particular when the booting RTA asks for an ID for this unit, 888 ** we must have set the BOOTED flag, and the NEWBOOT flag is used 889 ** to force an open on any ports that where previously open on this 890 ** unit. 891 */ 892 for ( entry=0; entry<MAX_RUP; entry++ ) 893 { 894 uint sysport; 895 896 if ((HostP->Mapping[entry].Flags & SLOT_IN_USE) && 897 (HostP->Mapping[entry].RtaUniqueNum==RtaUniq)) 898 { 899 HostP->Mapping[entry].Flags |= RTA_BOOTED|RTA_NEWBOOT; 900#if NEED_TO_FIX 901 RIO_SV_BROADCAST(HostP->svFlags[entry]); 902#endif 903 if ( (sysport=HostP->Mapping[entry].SysPort) != NO_PORT ) 904 { 905 if ( sysport < p->RIOFirstPortsBooted ) 906 p->RIOFirstPortsBooted = sysport; 907 if ( sysport > p->RIOLastPortsBooted ) 908 p->RIOLastPortsBooted = sysport; 909 /* 910 ** For a 16 port RTA, check the second bank of 8 ports 911 */ 912 if (RtaType == TYPE_RTA16) 913 { 914 entry2 = HostP->Mapping[entry].ID2 - 1; 915 HostP->Mapping[entry2].Flags |= RTA_BOOTED|RTA_NEWBOOT; 916#if NEED_TO_FIX 917 RIO_SV_BROADCAST(HostP->svFlags[entry2]); 918#endif 919 sysport = HostP->Mapping[entry2].SysPort; 920 if ( sysport < p->RIOFirstPortsBooted ) 921 p->RIOFirstPortsBooted = sysport; 922 if ( sysport > p->RIOLastPortsBooted ) 923 p->RIOLastPortsBooted = sysport; 924 } 925 } 926 if (RtaType == TYPE_RTA16) { 927 rio_dprintk (RIO_DEBUG_BOOT, "RTA will be given IDs %d+%d\n", 928 entry+1, entry2+1); 929 } else { 930 rio_dprintk (RIO_DEBUG_BOOT, "RTA will be given ID %d\n",entry+1); 931 } 932 return TRUE; 933 } 934 } 935 936 rio_dprintk (RIO_DEBUG_BOOT, "RTA not configured for this host\n"); 937 938 if ( Rup >= (ushort)MAX_RUP ) 939 { 940 /* 941 ** It was a host that did the booting 942 */ 943 MyType = "Host"; 944 MyName = HostP->Name; 945 } 946 else 947 { 948 /* 949 ** It was an RTA that did the booting 950 */ 951 MyType = "RTA"; 952 MyName = HostP->Mapping[Rup].Name; 953 } 954#ifdef CHECK 955 CheckString(MyType); 956 CheckString(MyName); 957#endif 958 959 MyLink = RBYTE(PktCmdP->LinkNum); 960 961 /* 962 ** There is no SLOT_IN_USE entry for this RTA attached to the current 963 ** host card in the driver table. 964 ** 965 ** Check for a SLOT_TENTATIVE entry for this RTA attached to the 966 ** current host card in the driver table. 967 ** 968 ** If we find one, then we re-use that slot. 969 */ 970 for ( entry=0; entry<MAX_RUP; entry++ ) 971 { 972 if ( (HostP->Mapping[entry].Flags & SLOT_TENTATIVE) && 973 (HostP->Mapping[entry].RtaUniqueNum == RtaUniq) ) 974 { 975 if (RtaType == TYPE_RTA16) 976 { 977 entry2 = HostP->Mapping[entry].ID2 - 1; 978 if ( (HostP->Mapping[entry2].Flags & SLOT_TENTATIVE) && 979 (HostP->Mapping[entry2].RtaUniqueNum == RtaUniq) ) 980 rio_dprintk (RIO_DEBUG_BOOT, "Found previous tentative slots (%d+%d)\n", 981 entry, entry2); 982 else 983 continue; 984 } 985 else 986 rio_dprintk (RIO_DEBUG_BOOT, "Found previous tentative slot (%d)\n",entry); 987 if (! p->RIONoMessage) 988 cprintf("RTA connected to %s '%s' (%c) not configured.\n",MyType,MyName,MyLink+'A'); 989 return TRUE; 990 } 991 } 992 993 /* 994 ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA 995 ** attached to the current host card in the driver table. 996 ** 997 ** Check if there is a SLOT_IN_USE or SLOT_TENTATIVE entry on another 998 ** host for this RTA in the driver table. 999 ** 1000 ** For a SLOT_IN_USE entry on another host, we need to delete the RTA 1001 ** entry from the other host and add it to this host (using some of 1002 ** the functions from table.c which do this). 1003 ** For a SLOT_TENTATIVE entry on another host, we must cope with the 1004 ** following scenario: 1005 ** 1006 ** + Plug 8 port RTA into host A. (This creates SLOT_TENTATIVE entry 1007 ** in table) 1008 ** + Unplug RTA and plug into host B. (We now have 2 SLOT_TENTATIVE 1009 ** entries) 1010 ** + Configure RTA on host B. (This slot now becomes SLOT_IN_USE) 1011 ** + Unplug RTA and plug back into host A. 1012 ** + Configure RTA on host A. We now have the same RTA configured 1013 ** with different ports on two different hosts. 1014 */ 1015 rio_dprintk (RIO_DEBUG_BOOT, "Have we seen RTA %x before?\n", RtaUniq ); 1016 found = 0; 1017 Flag = 0; /* Convince the compiler this variable is initialized */ 1018 for ( host = 0; !found && (host < p->RIONumHosts); host++ ) 1019 { 1020 for ( rta=0; rta<MAX_RUP; rta++ ) 1021 { 1022 if ((p->RIOHosts[host].Mapping[rta].Flags & 1023 (SLOT_IN_USE | SLOT_TENTATIVE)) && 1024 (p->RIOHosts[host].Mapping[rta].RtaUniqueNum==RtaUniq)) 1025 { 1026 Flag = p->RIOHosts[host].Mapping[rta].Flags; 1027 MapP = &p->RIOHosts[host].Mapping[rta]; 1028 if (RtaType == TYPE_RTA16) 1029 { 1030 MapP2 = &p->RIOHosts[host].Mapping[MapP->ID2 - 1]; 1031 rio_dprintk (RIO_DEBUG_BOOT, "This RTA is units %d+%d from host %s\n", 1032 rta+1, MapP->ID2, p->RIOHosts[host].Name); 1033 } 1034 else 1035 rio_dprintk (RIO_DEBUG_BOOT, "This RTA is unit %d from host %s\n", 1036 rta+1, p->RIOHosts[host].Name); 1037 found = 1; 1038 break; 1039 } 1040 } 1041 } 1042 1043 /* 1044 ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA 1045 ** attached to the current host card in the driver table. 1046 ** 1047 ** If we have not found a SLOT_IN_USE or SLOT_TENTATIVE entry on 1048 ** another host for this RTA in the driver table... 1049 ** 1050 ** Check for a SLOT_IN_USE entry for this RTA in the config table. 1051 */ 1052 if ( !MapP ) 1053 { 1054 rio_dprintk (RIO_DEBUG_BOOT, "Look for RTA %x in RIOSavedTable\n",RtaUniq); 1055 for ( rta=0; rta < TOTAL_MAP_ENTRIES; rta++ ) 1056 { 1057 rio_dprintk (RIO_DEBUG_BOOT, "Check table entry %d (%x)", 1058 rta, 1059 p->RIOSavedTable[rta].RtaUniqueNum); 1060 1061 if ( (p->RIOSavedTable[rta].Flags & SLOT_IN_USE) && 1062 (p->RIOSavedTable[rta].RtaUniqueNum == RtaUniq) ) 1063 { 1064 MapP = &p->RIOSavedTable[rta]; 1065 Flag = p->RIOSavedTable[rta].Flags; 1066 if (RtaType == TYPE_RTA16) 1067 { 1068 for (entry2 = rta + 1; entry2 < TOTAL_MAP_ENTRIES; 1069 entry2++) 1070 { 1071 if (p->RIOSavedTable[entry2].RtaUniqueNum == RtaUniq) 1072 break; 1073 } 1074 MapP2 = &p->RIOSavedTable[entry2]; 1075 rio_dprintk (RIO_DEBUG_BOOT, "This RTA is from table entries %d+%d\n", 1076 rta, entry2); 1077 } 1078 else 1079 rio_dprintk (RIO_DEBUG_BOOT, "This RTA is from table entry %d\n", rta); 1080 break; 1081 } 1082 } 1083 } 1084 1085 /* 1086 ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA 1087 ** attached to the current host card in the driver table. 1088 ** 1089 ** We may have found a SLOT_IN_USE entry on another host for this 1090 ** RTA in the config table, or a SLOT_IN_USE or SLOT_TENTATIVE entry 1091 ** on another host for this RTA in the driver table. 1092 ** 1093 ** Check the driver table for room to fit this newly discovered RTA. 1094 ** RIOFindFreeID() first looks for free slots and if it does not 1095 ** find any free slots it will then attempt to oust any 1096 ** tentative entry in the table. 1097 */ 1098 EmptySlot = 1; 1099 if (RtaType == TYPE_RTA16) 1100 { 1101 if (RIOFindFreeID(p, HostP, &entry, &entry2) == 0) 1102 { 1103 RIODefaultName(p, HostP, entry); 1104 FillSlot(entry, entry2, RtaUniq, HostP); 1105 EmptySlot = 0; 1106 } 1107 } 1108 else 1109 { 1110 if (RIOFindFreeID(p, HostP, &entry, NULL) == 0) 1111 { 1112 RIODefaultName(p, HostP, entry); 1113 FillSlot(entry, 0, RtaUniq, HostP); 1114 EmptySlot = 0; 1115 } 1116 } 1117 1118 /* 1119 ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA 1120 ** attached to the current host card in the driver table. 1121 ** 1122 ** If we found a SLOT_IN_USE entry on another host for this 1123 ** RTA in the config or driver table, and there are enough free 1124 ** slots in the driver table, then we need to move it over and 1125 ** delete it from the other host. 1126 ** If we found a SLOT_TENTATIVE entry on another host for this 1127 ** RTA in the driver table, just delete the other host entry. 1128 */ 1129 if (EmptySlot == 0) 1130 { 1131 if ( MapP ) 1132 { 1133 if (Flag & SLOT_IN_USE) 1134 { 1135 rio_dprintk (RIO_DEBUG_BOOT, 1136 "This RTA configured on another host - move entry to current host (1)\n"); 1137 HostP->Mapping[entry].SysPort = MapP->SysPort; 1138 CCOPY( MapP->Name, HostP->Mapping[entry].Name, MAX_NAME_LEN ); 1139 HostP->Mapping[entry].Flags = 1140 SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT; 1141#if NEED_TO_FIX 1142 RIO_SV_BROADCAST(HostP->svFlags[entry]); 1143#endif 1144 RIOReMapPorts( p, HostP, &HostP->Mapping[entry] ); 1145 if ( HostP->Mapping[entry].SysPort < p->RIOFirstPortsBooted ) 1146 p->RIOFirstPortsBooted = HostP->Mapping[entry].SysPort; 1147 if ( HostP->Mapping[entry].SysPort > p->RIOLastPortsBooted ) 1148 p->RIOLastPortsBooted = HostP->Mapping[entry].SysPort; 1149 rio_dprintk (RIO_DEBUG_BOOT, "SysPort %d, Name %s\n",(int)MapP->SysPort,MapP->Name); 1150 } 1151 else 1152 { 1153 rio_dprintk (RIO_DEBUG_BOOT, 1154 "This RTA has a tentative entry on another host - delete that entry (1)\n"); 1155 HostP->Mapping[entry].Flags = 1156 SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT; 1157#if NEED_TO_FIX 1158 RIO_SV_BROADCAST(HostP->svFlags[entry]); 1159#endif 1160 } 1161 if (RtaType == TYPE_RTA16) 1162 { 1163 if (Flag & SLOT_IN_USE) 1164 { 1165 HostP->Mapping[entry2].Flags = SLOT_IN_USE | 1166 RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; 1167#if NEED_TO_FIX 1168 RIO_SV_BROADCAST(HostP->svFlags[entry2]); 1169#endif 1170 HostP->Mapping[entry2].SysPort = MapP2->SysPort; 1171 /* 1172 ** Map second block of ttys for 16 port RTA 1173 */ 1174 RIOReMapPorts( p, HostP, &HostP->Mapping[entry2] ); 1175 if (HostP->Mapping[entry2].SysPort < p->RIOFirstPortsBooted) 1176 p->RIOFirstPortsBooted = HostP->Mapping[entry2].SysPort; 1177 if (HostP->Mapping[entry2].SysPort > p->RIOLastPortsBooted) 1178 p->RIOLastPortsBooted = HostP->Mapping[entry2].SysPort; 1179 rio_dprintk (RIO_DEBUG_BOOT, "SysPort %d, Name %s\n", 1180 (int)HostP->Mapping[entry2].SysPort, 1181 HostP->Mapping[entry].Name); 1182 } 1183 else 1184 HostP->Mapping[entry2].Flags = SLOT_TENTATIVE | 1185 RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; 1186#if NEED_TO_FIX 1187 RIO_SV_BROADCAST(HostP->svFlags[entry2]); 1188#endif 1189 bzero( (caddr_t)MapP2, sizeof(struct Map) ); 1190 } 1191 bzero( (caddr_t)MapP, sizeof(struct Map) ); 1192 if (! p->RIONoMessage) 1193 cprintf("An orphaned RTA has been adopted by %s '%s' (%c).\n",MyType,MyName,MyLink+'A'); 1194 } 1195 else if (! p->RIONoMessage) 1196 cprintf("RTA connected to %s '%s' (%c) not configured.\n",MyType,MyName,MyLink+'A'); 1197 RIOSetChange(p); 1198 return TRUE; 1199 } 1200 1201 /* 1202 ** There is no room in the driver table to make an entry for the 1203 ** booted RTA. Keep a note of its Uniq Num in the overflow table, 1204 ** so we can ignore it's ID requests. 1205 */ 1206 if (! p->RIONoMessage) 1207 cprintf("The RTA connected to %s '%s' (%c) cannot be configured. You cannot configure more than 128 ports to one host card.\n",MyType,MyName,MyLink+'A'); 1208 for ( entry=0; entry<HostP->NumExtraBooted; entry++ ) 1209 { 1210 if ( HostP->ExtraUnits[entry] == RtaUniq ) 1211 { 1212 /* 1213 ** already got it! 1214 */ 1215 return TRUE; 1216 } 1217 } 1218 /* 1219 ** If there is room, add the unit to the list of extras 1220 */ 1221 if ( HostP->NumExtraBooted < MAX_EXTRA_UNITS ) 1222 HostP->ExtraUnits[HostP->NumExtraBooted++] = RtaUniq; 1223 return TRUE; 1224} 1225 1226 1227/* 1228** If the RTA or its host appears in the RIOBindTab[] structure then 1229** we mustn't boot the RTA and should return FALSE. 1230** This operation is slightly different from the other drivers for RIO 1231** in that this is designed to work with the new utilities 1232** not config.rio and is FAR SIMPLER. 1233** We no longer support the RIOBootMode variable. It is all done from the 1234** "boot/noboot" field in the rio.cf file. 1235*/ 1236int 1237RIOBootOk(p, HostP, RtaUniq) 1238struct rio_info * p; 1239struct Host * HostP; 1240ulong RtaUniq; 1241{ 1242 int Entry; 1243 uint HostUniq = HostP->UniqueNum; 1244 1245 /* 1246 ** Search bindings table for RTA or its parent. 1247 ** If it exists, return 0, else 1. 1248 */ 1249 for (Entry = 0; 1250 ( Entry < MAX_RTA_BINDINGS ) && ( p->RIOBindTab[Entry] != 0 ); 1251 Entry++) 1252 { 1253 if ( (p->RIOBindTab[Entry] == HostUniq) || 1254 (p->RIOBindTab[Entry] == RtaUniq) ) 1255 return 0; 1256 } 1257 return 1; 1258} 1259 1260/* 1261** Make an empty slot tentative. If this is a 16 port RTA, make both 1262** slots tentative, and the second one RTA_SECOND_SLOT as well. 1263*/ 1264 1265void 1266FillSlot(entry, entry2, RtaUniq, HostP) 1267int entry; 1268int entry2; 1269uint RtaUniq; 1270struct Host *HostP; 1271{ 1272 int link; 1273 1274 rio_dprintk (RIO_DEBUG_BOOT, "FillSlot(%d, %d, 0x%x...)\n", entry, entry2, RtaUniq); 1275 1276 HostP->Mapping[entry].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE); 1277 HostP->Mapping[entry].SysPort = NO_PORT; 1278 HostP->Mapping[entry].RtaUniqueNum = RtaUniq; 1279 HostP->Mapping[entry].HostUniqueNum = HostP->UniqueNum; 1280 HostP->Mapping[entry].ID = entry + 1; 1281 HostP->Mapping[entry].ID2 = 0; 1282 if (entry2) { 1283 HostP->Mapping[entry2].Flags = (RTA_BOOTED | RTA_NEWBOOT | 1284 SLOT_TENTATIVE | RTA16_SECOND_SLOT); 1285 HostP->Mapping[entry2].SysPort = NO_PORT; 1286 HostP->Mapping[entry2].RtaUniqueNum = RtaUniq; 1287 HostP->Mapping[entry2].HostUniqueNum = HostP->UniqueNum; 1288 HostP->Mapping[entry2].Name[0] = '\0'; 1289 HostP->Mapping[entry2].ID = entry2 + 1; 1290 HostP->Mapping[entry2].ID2 = entry + 1; 1291 HostP->Mapping[entry].ID2 = entry2 + 1; 1292 } 1293 /* 1294 ** Must set these up, so that utilities show 1295 ** topology of 16 port RTAs correctly 1296 */ 1297 for ( link=0; link<LINKS_PER_UNIT; link++ ) { 1298 HostP->Mapping[entry].Topology[link].Unit = ROUTE_DISCONNECT; 1299 HostP->Mapping[entry].Topology[link].Link = NO_LINK; 1300 if (entry2) { 1301 HostP->Mapping[entry2].Topology[link].Unit = ROUTE_DISCONNECT; 1302 HostP->Mapping[entry2].Topology[link].Link = NO_LINK; 1303 } 1304 } 1305} 1306 1307