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