rioboot.c 39 KB

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