rioboot.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360
  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. #ifdef CHECK
  579. CheckHost(Host);
  580. CheckRup(Rup);
  581. CheckHostP(HostP);
  582. CheckPacketP(PacketP);
  583. #endif
  584. /*
  585. ** If we haven't been told what to boot, we can't boot it.
  586. */
  587. if ( p->RIONumBootPkts == 0 ) {
  588. rio_dprintk (RIO_DEBUG_BOOT, "No RTA code to download yet\n");
  589. return 0;
  590. }
  591. /* rio_dprint(RIO_DEBUG_BOOT, NULL,DBG_BOOT,"Incoming command packet\n"); */
  592. /* ShowPacket( DBG_BOOT, PacketP ); */
  593. /*
  594. ** Special case of boot completed - if we get one of these then we
  595. ** don't need a command block. For all other cases we do, so handle
  596. ** this first and then get a command block, then handle every other
  597. ** case, relinquishing the command block if disaster strikes!
  598. */
  599. if ( (RBYTE(PacketP->len) & PKT_CMD_BIT) &&
  600. (RBYTE(PktCmdP->Command)==BOOT_COMPLETED) )
  601. return RIOBootComplete(p, HostP, Rup, PktCmdP );
  602. /*
  603. ** try to unhook a command block from the command free list.
  604. */
  605. if ( !(CmdBlkP = RIOGetCmdBlk()) ) {
  606. rio_dprintk (RIO_DEBUG_BOOT, "No command blocks to boot RTA! come back later.\n");
  607. return 0;
  608. }
  609. /*
  610. ** Fill in the default info on the command block
  611. */
  612. CmdBlkP->Packet.dest_unit = Rup < (ushort)MAX_RUP ? Rup : 0;
  613. CmdBlkP->Packet.dest_port = BOOT_RUP;
  614. CmdBlkP->Packet.src_unit = 0;
  615. CmdBlkP->Packet.src_port = BOOT_RUP;
  616. CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL;
  617. PktReplyP = (struct PktCmd_M *)CmdBlkP->Packet.data;
  618. /*
  619. ** process COMMANDS on the boot rup!
  620. */
  621. if ( RBYTE(PacketP->len) & PKT_CMD_BIT ) {
  622. /*
  623. ** We only expect one type of command - a BOOT_REQUEST!
  624. */
  625. if ( RBYTE(PktCmdP->Command) != BOOT_REQUEST ) {
  626. rio_dprintk (RIO_DEBUG_BOOT, "Unexpected command %d on BOOT RUP %d of host %d\n",
  627. PktCmdP->Command,Rup,HostP-p->RIOHosts);
  628. ShowPacket( DBG_BOOT, PacketP );
  629. RIOFreeCmdBlk( CmdBlkP );
  630. return 1;
  631. }
  632. /*
  633. ** Build a Boot Sequence command block
  634. **
  635. ** 02.03.1999 ARG - ESIL 0820 fix
  636. ** We no longer need to use "Boot Mode", we'll always allow
  637. ** boot requests - the boot will not complete if the device
  638. ** appears in the bindings table.
  639. ** So, this conditional is not required ...
  640. **
  641. if (p->RIOBootMode == RC_BOOT_NONE)
  642. **
  643. ** If the system is in slave mode, and a boot request is
  644. ** received, set command to BOOT_ABORT so that the boot
  645. ** will not complete.
  646. **
  647. PktReplyP->Command = BOOT_ABORT;
  648. else
  649. **
  650. ** We'll just (always) set the command field in packet reply
  651. ** to allow an attempted boot sequence :
  652. */
  653. PktReplyP->Command = BOOT_SEQUENCE;
  654. PktReplyP->BootSequence.NumPackets = p->RIONumBootPkts;
  655. PktReplyP->BootSequence.LoadBase = p->RIOConf.RtaLoadBase;
  656. PktReplyP->BootSequence.CodeSize = p->RIOBootCount;
  657. CmdBlkP->Packet.len = BOOT_SEQUENCE_LEN | PKT_CMD_BIT;
  658. bcopy("BOOT",(void *)&CmdBlkP->Packet.data[BOOT_SEQUENCE_LEN],4);
  659. rio_dprintk (RIO_DEBUG_BOOT, "Boot RTA on Host %d Rup %d - %d (0x%x) packets to 0x%x\n",
  660. HostP-p->RIOHosts, Rup, p->RIONumBootPkts, p->RIONumBootPkts,
  661. p->RIOConf.RtaLoadBase);
  662. /*
  663. ** If this host is in slave mode, send the RTA an invalid boot
  664. ** sequence command block to force it to kill the boot. We wait
  665. ** for half a second before sending this packet to prevent the RTA
  666. ** attempting to boot too often. The master host should then grab
  667. ** the RTA and make it its own.
  668. */
  669. p->RIOBooting++;
  670. RIOQueueCmdBlk( HostP, Rup, CmdBlkP );
  671. return 1;
  672. }
  673. /*
  674. ** It is a request for boot data.
  675. */
  676. sequence = RWORD(PktCmdP->Sequence);
  677. rio_dprintk (RIO_DEBUG_BOOT, "Boot block %d on Host %d Rup%d\n",sequence,HostP-p->RIOHosts,Rup);
  678. if ( sequence >= p->RIONumBootPkts ) {
  679. rio_dprintk (RIO_DEBUG_BOOT, "Got a request for packet %d, max is %d\n", sequence,
  680. p->RIONumBootPkts);
  681. ShowPacket( DBG_BOOT, PacketP );
  682. }
  683. PktReplyP->Sequence = sequence;
  684. bcopy( p->RIOBootPackets[ p->RIONumBootPkts - sequence - 1 ],
  685. PktReplyP->BootData, RTA_BOOT_DATA_SIZE );
  686. CmdBlkP->Packet.len = PKT_MAX_DATA_LEN;
  687. ShowPacket( DBG_BOOT, &CmdBlkP->Packet );
  688. RIOQueueCmdBlk( HostP, Rup, CmdBlkP );
  689. return 1;
  690. }
  691. /*
  692. ** This function is called when an RTA been booted.
  693. ** If booted by a host, HostP->HostUniqueNum is the booting host.
  694. ** If booted by an RTA, HostP->Mapping[Rup].RtaUniqueNum is the booting RTA.
  695. ** RtaUniq is the booted RTA.
  696. */
  697. static int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct PktCmd *PktCmdP )
  698. {
  699. struct Map *MapP = NULL;
  700. struct Map *MapP2 = NULL;
  701. int Flag;
  702. int found;
  703. int host, rta;
  704. int EmptySlot = -1;
  705. int entry, entry2;
  706. char *MyType, *MyName;
  707. uint MyLink;
  708. ushort RtaType;
  709. uint RtaUniq = (RBYTE(PktCmdP->UniqNum[0])) +
  710. (RBYTE(PktCmdP->UniqNum[1]) << 8) +
  711. (RBYTE(PktCmdP->UniqNum[2]) << 16) +
  712. (RBYTE(PktCmdP->UniqNum[3]) << 24);
  713. /* Was RIOBooting-- . That's bad. If an RTA sends two of them, the
  714. driver will never think that the RTA has booted... -- REW */
  715. p->RIOBooting = 0;
  716. rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot completed - BootInProgress now %d\n", p->RIOBooting);
  717. /*
  718. ** Determine type of unit (16/8 port RTA).
  719. */
  720. RtaType = GetUnitType(RtaUniq);
  721. if ( Rup >= (ushort)MAX_RUP ) {
  722. rio_dprintk (RIO_DEBUG_BOOT, "RIO: Host %s has booted an RTA(%d) on link %c\n",
  723. HostP->Name, 8 * RtaType, RBYTE(PktCmdP->LinkNum)+'A');
  724. } else {
  725. rio_dprintk (RIO_DEBUG_BOOT, "RIO: RTA %s has booted an RTA(%d) on link %c\n",
  726. HostP->Mapping[Rup].Name, 8 * RtaType,
  727. RBYTE(PktCmdP->LinkNum)+'A');
  728. }
  729. rio_dprintk (RIO_DEBUG_BOOT, "UniqNum is 0x%x\n",RtaUniq);
  730. if ( ( RtaUniq == 0x00000000 ) || ( RtaUniq == 0xffffffff ) )
  731. {
  732. rio_dprintk (RIO_DEBUG_BOOT, "Illegal RTA Uniq Number\n");
  733. return TRUE;
  734. }
  735. /*
  736. ** If this RTA has just booted an RTA which doesn't belong to this
  737. ** system, or the system is in slave mode, do not attempt to create
  738. ** a new table entry for it.
  739. */
  740. if (!RIOBootOk(p, HostP, RtaUniq))
  741. {
  742. MyLink = RBYTE(PktCmdP->LinkNum);
  743. if (Rup < (ushort) MAX_RUP)
  744. {
  745. /*
  746. ** RtaUniq was clone booted (by this RTA). Instruct this RTA
  747. ** to hold off further attempts to boot on this link for 30
  748. ** seconds.
  749. */
  750. if (RIOSuspendBootRta(HostP, HostP->Mapping[Rup].ID, MyLink))
  751. {
  752. rio_dprintk (RIO_DEBUG_BOOT, "RTA failed to suspend booting on link %c\n",
  753. 'A' + MyLink);
  754. }
  755. }
  756. else
  757. {
  758. /*
  759. ** RtaUniq was booted by this host. Set the booting link
  760. ** to hold off for 30 seconds to give another unit a
  761. ** chance to boot it.
  762. */
  763. WWORD(HostP->LinkStrP[MyLink].WaitNoBoot, 30);
  764. }
  765. rio_dprintk (RIO_DEBUG_BOOT, "RTA %x not owned - suspend booting down link %c on unit %x\n",
  766. RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum);
  767. return TRUE;
  768. }
  769. /*
  770. ** Check for a SLOT_IN_USE entry for this RTA attached to the
  771. ** current host card in the driver table.
  772. **
  773. ** If it exists, make a note that we have booted it. Other parts of
  774. ** the driver are interested in this information at a later date,
  775. ** in particular when the booting RTA asks for an ID for this unit,
  776. ** we must have set the BOOTED flag, and the NEWBOOT flag is used
  777. ** to force an open on any ports that where previously open on this
  778. ** unit.
  779. */
  780. for ( entry=0; entry<MAX_RUP; entry++ )
  781. {
  782. uint sysport;
  783. if ((HostP->Mapping[entry].Flags & SLOT_IN_USE) &&
  784. (HostP->Mapping[entry].RtaUniqueNum==RtaUniq))
  785. {
  786. HostP->Mapping[entry].Flags |= RTA_BOOTED|RTA_NEWBOOT;
  787. #ifdef NEED_TO_FIX
  788. RIO_SV_BROADCAST(HostP->svFlags[entry]);
  789. #endif
  790. if ( (sysport=HostP->Mapping[entry].SysPort) != NO_PORT )
  791. {
  792. if ( sysport < p->RIOFirstPortsBooted )
  793. p->RIOFirstPortsBooted = sysport;
  794. if ( sysport > p->RIOLastPortsBooted )
  795. p->RIOLastPortsBooted = sysport;
  796. /*
  797. ** For a 16 port RTA, check the second bank of 8 ports
  798. */
  799. if (RtaType == TYPE_RTA16)
  800. {
  801. entry2 = HostP->Mapping[entry].ID2 - 1;
  802. HostP->Mapping[entry2].Flags |= RTA_BOOTED|RTA_NEWBOOT;
  803. #ifdef NEED_TO_FIX
  804. RIO_SV_BROADCAST(HostP->svFlags[entry2]);
  805. #endif
  806. sysport = HostP->Mapping[entry2].SysPort;
  807. if ( sysport < p->RIOFirstPortsBooted )
  808. p->RIOFirstPortsBooted = sysport;
  809. if ( sysport > p->RIOLastPortsBooted )
  810. p->RIOLastPortsBooted = sysport;
  811. }
  812. }
  813. if (RtaType == TYPE_RTA16) {
  814. rio_dprintk (RIO_DEBUG_BOOT, "RTA will be given IDs %d+%d\n",
  815. entry+1, entry2+1);
  816. } else {
  817. rio_dprintk (RIO_DEBUG_BOOT, "RTA will be given ID %d\n",entry+1);
  818. }
  819. return TRUE;
  820. }
  821. }
  822. rio_dprintk (RIO_DEBUG_BOOT, "RTA not configured for this host\n");
  823. if ( Rup >= (ushort)MAX_RUP )
  824. {
  825. /*
  826. ** It was a host that did the booting
  827. */
  828. MyType = "Host";
  829. MyName = HostP->Name;
  830. }
  831. else
  832. {
  833. /*
  834. ** It was an RTA that did the booting
  835. */
  836. MyType = "RTA";
  837. MyName = HostP->Mapping[Rup].Name;
  838. }
  839. #ifdef CHECK
  840. CheckString(MyType);
  841. CheckString(MyName);
  842. #endif
  843. MyLink = RBYTE(PktCmdP->LinkNum);
  844. /*
  845. ** There is no SLOT_IN_USE entry for this RTA attached to the current
  846. ** host card in the driver table.
  847. **
  848. ** Check for a SLOT_TENTATIVE entry for this RTA attached to the
  849. ** current host card in the driver table.
  850. **
  851. ** If we find one, then we re-use that slot.
  852. */
  853. for ( entry=0; entry<MAX_RUP; entry++ )
  854. {
  855. if ( (HostP->Mapping[entry].Flags & SLOT_TENTATIVE) &&
  856. (HostP->Mapping[entry].RtaUniqueNum == RtaUniq) )
  857. {
  858. if (RtaType == TYPE_RTA16)
  859. {
  860. entry2 = HostP->Mapping[entry].ID2 - 1;
  861. if ( (HostP->Mapping[entry2].Flags & SLOT_TENTATIVE) &&
  862. (HostP->Mapping[entry2].RtaUniqueNum == RtaUniq) )
  863. rio_dprintk (RIO_DEBUG_BOOT, "Found previous tentative slots (%d+%d)\n",
  864. entry, entry2);
  865. else
  866. continue;
  867. }
  868. else
  869. rio_dprintk (RIO_DEBUG_BOOT, "Found previous tentative slot (%d)\n",entry);
  870. if (! p->RIONoMessage)
  871. cprintf("RTA connected to %s '%s' (%c) not configured.\n",MyType,MyName,MyLink+'A');
  872. return TRUE;
  873. }
  874. }
  875. /*
  876. ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA
  877. ** attached to the current host card in the driver table.
  878. **
  879. ** Check if there is a SLOT_IN_USE or SLOT_TENTATIVE entry on another
  880. ** host for this RTA in the driver table.
  881. **
  882. ** For a SLOT_IN_USE entry on another host, we need to delete the RTA
  883. ** entry from the other host and add it to this host (using some of
  884. ** the functions from table.c which do this).
  885. ** For a SLOT_TENTATIVE entry on another host, we must cope with the
  886. ** following scenario:
  887. **
  888. ** + Plug 8 port RTA into host A. (This creates SLOT_TENTATIVE entry
  889. ** in table)
  890. ** + Unplug RTA and plug into host B. (We now have 2 SLOT_TENTATIVE
  891. ** entries)
  892. ** + Configure RTA on host B. (This slot now becomes SLOT_IN_USE)
  893. ** + Unplug RTA and plug back into host A.
  894. ** + Configure RTA on host A. We now have the same RTA configured
  895. ** with different ports on two different hosts.
  896. */
  897. rio_dprintk (RIO_DEBUG_BOOT, "Have we seen RTA %x before?\n", RtaUniq );
  898. found = 0;
  899. Flag = 0; /* Convince the compiler this variable is initialized */
  900. for ( host = 0; !found && (host < p->RIONumHosts); host++ )
  901. {
  902. for ( rta=0; rta<MAX_RUP; rta++ )
  903. {
  904. if ((p->RIOHosts[host].Mapping[rta].Flags &
  905. (SLOT_IN_USE | SLOT_TENTATIVE)) &&
  906. (p->RIOHosts[host].Mapping[rta].RtaUniqueNum==RtaUniq))
  907. {
  908. Flag = p->RIOHosts[host].Mapping[rta].Flags;
  909. MapP = &p->RIOHosts[host].Mapping[rta];
  910. if (RtaType == TYPE_RTA16)
  911. {
  912. MapP2 = &p->RIOHosts[host].Mapping[MapP->ID2 - 1];
  913. rio_dprintk (RIO_DEBUG_BOOT, "This RTA is units %d+%d from host %s\n",
  914. rta+1, MapP->ID2, p->RIOHosts[host].Name);
  915. }
  916. else
  917. rio_dprintk (RIO_DEBUG_BOOT, "This RTA is unit %d from host %s\n",
  918. rta+1, p->RIOHosts[host].Name);
  919. found = 1;
  920. break;
  921. }
  922. }
  923. }
  924. /*
  925. ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA
  926. ** attached to the current host card in the driver table.
  927. **
  928. ** If we have not found a SLOT_IN_USE or SLOT_TENTATIVE entry on
  929. ** another host for this RTA in the driver table...
  930. **
  931. ** Check for a SLOT_IN_USE entry for this RTA in the config table.
  932. */
  933. if ( !MapP )
  934. {
  935. rio_dprintk (RIO_DEBUG_BOOT, "Look for RTA %x in RIOSavedTable\n",RtaUniq);
  936. for ( rta=0; rta < TOTAL_MAP_ENTRIES; rta++ )
  937. {
  938. rio_dprintk (RIO_DEBUG_BOOT, "Check table entry %d (%x)",
  939. rta,
  940. p->RIOSavedTable[rta].RtaUniqueNum);
  941. if ( (p->RIOSavedTable[rta].Flags & SLOT_IN_USE) &&
  942. (p->RIOSavedTable[rta].RtaUniqueNum == RtaUniq) )
  943. {
  944. MapP = &p->RIOSavedTable[rta];
  945. Flag = p->RIOSavedTable[rta].Flags;
  946. if (RtaType == TYPE_RTA16)
  947. {
  948. for (entry2 = rta + 1; entry2 < TOTAL_MAP_ENTRIES;
  949. entry2++)
  950. {
  951. if (p->RIOSavedTable[entry2].RtaUniqueNum == RtaUniq)
  952. break;
  953. }
  954. MapP2 = &p->RIOSavedTable[entry2];
  955. rio_dprintk (RIO_DEBUG_BOOT, "This RTA is from table entries %d+%d\n",
  956. rta, entry2);
  957. }
  958. else
  959. rio_dprintk (RIO_DEBUG_BOOT, "This RTA is from table entry %d\n", rta);
  960. break;
  961. }
  962. }
  963. }
  964. /*
  965. ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA
  966. ** attached to the current host card in the driver table.
  967. **
  968. ** We may have found a SLOT_IN_USE entry on another host for this
  969. ** RTA in the config table, or a SLOT_IN_USE or SLOT_TENTATIVE entry
  970. ** on another host for this RTA in the driver table.
  971. **
  972. ** Check the driver table for room to fit this newly discovered RTA.
  973. ** RIOFindFreeID() first looks for free slots and if it does not
  974. ** find any free slots it will then attempt to oust any
  975. ** tentative entry in the table.
  976. */
  977. EmptySlot = 1;
  978. if (RtaType == TYPE_RTA16)
  979. {
  980. if (RIOFindFreeID(p, HostP, &entry, &entry2) == 0)
  981. {
  982. RIODefaultName(p, HostP, entry);
  983. FillSlot(entry, entry2, RtaUniq, HostP);
  984. EmptySlot = 0;
  985. }
  986. }
  987. else
  988. {
  989. if (RIOFindFreeID(p, HostP, &entry, NULL) == 0)
  990. {
  991. RIODefaultName(p, HostP, entry);
  992. FillSlot(entry, 0, RtaUniq, HostP);
  993. EmptySlot = 0;
  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. ** If we found a SLOT_IN_USE entry on another host for this
  1001. ** RTA in the config or driver table, and there are enough free
  1002. ** slots in the driver table, then we need to move it over and
  1003. ** delete it from the other host.
  1004. ** If we found a SLOT_TENTATIVE entry on another host for this
  1005. ** RTA in the driver table, just delete the other host entry.
  1006. */
  1007. if (EmptySlot == 0)
  1008. {
  1009. if ( MapP )
  1010. {
  1011. if (Flag & SLOT_IN_USE)
  1012. {
  1013. rio_dprintk (RIO_DEBUG_BOOT,
  1014. "This RTA configured on another host - move entry to current host (1)\n");
  1015. HostP->Mapping[entry].SysPort = MapP->SysPort;
  1016. CCOPY( MapP->Name, HostP->Mapping[entry].Name, MAX_NAME_LEN );
  1017. HostP->Mapping[entry].Flags =
  1018. SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT;
  1019. #ifdef NEED_TO_FIX
  1020. RIO_SV_BROADCAST(HostP->svFlags[entry]);
  1021. #endif
  1022. RIOReMapPorts( p, HostP, &HostP->Mapping[entry] );
  1023. if ( HostP->Mapping[entry].SysPort < p->RIOFirstPortsBooted )
  1024. p->RIOFirstPortsBooted = HostP->Mapping[entry].SysPort;
  1025. if ( HostP->Mapping[entry].SysPort > p->RIOLastPortsBooted )
  1026. p->RIOLastPortsBooted = HostP->Mapping[entry].SysPort;
  1027. rio_dprintk (RIO_DEBUG_BOOT, "SysPort %d, Name %s\n",(int)MapP->SysPort,MapP->Name);
  1028. }
  1029. else
  1030. {
  1031. rio_dprintk (RIO_DEBUG_BOOT,
  1032. "This RTA has a tentative entry on another host - delete that entry (1)\n");
  1033. HostP->Mapping[entry].Flags =
  1034. SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT;
  1035. #ifdef NEED_TO_FIX
  1036. RIO_SV_BROADCAST(HostP->svFlags[entry]);
  1037. #endif
  1038. }
  1039. if (RtaType == TYPE_RTA16)
  1040. {
  1041. if (Flag & SLOT_IN_USE)
  1042. {
  1043. HostP->Mapping[entry2].Flags = SLOT_IN_USE |
  1044. RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT;
  1045. #ifdef NEED_TO_FIX
  1046. RIO_SV_BROADCAST(HostP->svFlags[entry2]);
  1047. #endif
  1048. HostP->Mapping[entry2].SysPort = MapP2->SysPort;
  1049. /*
  1050. ** Map second block of ttys for 16 port RTA
  1051. */
  1052. RIOReMapPorts( p, HostP, &HostP->Mapping[entry2] );
  1053. if (HostP->Mapping[entry2].SysPort < p->RIOFirstPortsBooted)
  1054. p->RIOFirstPortsBooted = HostP->Mapping[entry2].SysPort;
  1055. if (HostP->Mapping[entry2].SysPort > p->RIOLastPortsBooted)
  1056. p->RIOLastPortsBooted = HostP->Mapping[entry2].SysPort;
  1057. rio_dprintk (RIO_DEBUG_BOOT, "SysPort %d, Name %s\n",
  1058. (int)HostP->Mapping[entry2].SysPort,
  1059. HostP->Mapping[entry].Name);
  1060. }
  1061. else
  1062. HostP->Mapping[entry2].Flags = SLOT_TENTATIVE |
  1063. RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT;
  1064. #ifdef NEED_TO_FIX
  1065. RIO_SV_BROADCAST(HostP->svFlags[entry2]);
  1066. #endif
  1067. bzero( (caddr_t)MapP2, sizeof(struct Map) );
  1068. }
  1069. bzero( (caddr_t)MapP, sizeof(struct Map) );
  1070. if (! p->RIONoMessage)
  1071. cprintf("An orphaned RTA has been adopted by %s '%s' (%c).\n",MyType,MyName,MyLink+'A');
  1072. }
  1073. else if (! p->RIONoMessage)
  1074. cprintf("RTA connected to %s '%s' (%c) not configured.\n",MyType,MyName,MyLink+'A');
  1075. RIOSetChange(p);
  1076. return TRUE;
  1077. }
  1078. /*
  1079. ** There is no room in the driver table to make an entry for the
  1080. ** booted RTA. Keep a note of its Uniq Num in the overflow table,
  1081. ** so we can ignore it's ID requests.
  1082. */
  1083. if (! p->RIONoMessage)
  1084. 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');
  1085. for ( entry=0; entry<HostP->NumExtraBooted; entry++ )
  1086. {
  1087. if ( HostP->ExtraUnits[entry] == RtaUniq )
  1088. {
  1089. /*
  1090. ** already got it!
  1091. */
  1092. return TRUE;
  1093. }
  1094. }
  1095. /*
  1096. ** If there is room, add the unit to the list of extras
  1097. */
  1098. if ( HostP->NumExtraBooted < MAX_EXTRA_UNITS )
  1099. HostP->ExtraUnits[HostP->NumExtraBooted++] = RtaUniq;
  1100. return TRUE;
  1101. }
  1102. /*
  1103. ** If the RTA or its host appears in the RIOBindTab[] structure then
  1104. ** we mustn't boot the RTA and should return FALSE.
  1105. ** This operation is slightly different from the other drivers for RIO
  1106. ** in that this is designed to work with the new utilities
  1107. ** not config.rio and is FAR SIMPLER.
  1108. ** We no longer support the RIOBootMode variable. It is all done from the
  1109. ** "boot/noboot" field in the rio.cf file.
  1110. */
  1111. int
  1112. RIOBootOk(p, HostP, RtaUniq)
  1113. struct rio_info * p;
  1114. struct Host * HostP;
  1115. ulong RtaUniq;
  1116. {
  1117. int Entry;
  1118. uint HostUniq = HostP->UniqueNum;
  1119. /*
  1120. ** Search bindings table for RTA or its parent.
  1121. ** If it exists, return 0, else 1.
  1122. */
  1123. for (Entry = 0;
  1124. ( Entry < MAX_RTA_BINDINGS ) && ( p->RIOBindTab[Entry] != 0 );
  1125. Entry++)
  1126. {
  1127. if ( (p->RIOBindTab[Entry] == HostUniq) ||
  1128. (p->RIOBindTab[Entry] == RtaUniq) )
  1129. return 0;
  1130. }
  1131. return 1;
  1132. }
  1133. /*
  1134. ** Make an empty slot tentative. If this is a 16 port RTA, make both
  1135. ** slots tentative, and the second one RTA_SECOND_SLOT as well.
  1136. */
  1137. void
  1138. FillSlot(entry, entry2, RtaUniq, HostP)
  1139. int entry;
  1140. int entry2;
  1141. uint RtaUniq;
  1142. struct Host *HostP;
  1143. {
  1144. int link;
  1145. rio_dprintk (RIO_DEBUG_BOOT, "FillSlot(%d, %d, 0x%x...)\n", entry, entry2, RtaUniq);
  1146. HostP->Mapping[entry].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE);
  1147. HostP->Mapping[entry].SysPort = NO_PORT;
  1148. HostP->Mapping[entry].RtaUniqueNum = RtaUniq;
  1149. HostP->Mapping[entry].HostUniqueNum = HostP->UniqueNum;
  1150. HostP->Mapping[entry].ID = entry + 1;
  1151. HostP->Mapping[entry].ID2 = 0;
  1152. if (entry2) {
  1153. HostP->Mapping[entry2].Flags = (RTA_BOOTED | RTA_NEWBOOT |
  1154. SLOT_TENTATIVE | RTA16_SECOND_SLOT);
  1155. HostP->Mapping[entry2].SysPort = NO_PORT;
  1156. HostP->Mapping[entry2].RtaUniqueNum = RtaUniq;
  1157. HostP->Mapping[entry2].HostUniqueNum = HostP->UniqueNum;
  1158. HostP->Mapping[entry2].Name[0] = '\0';
  1159. HostP->Mapping[entry2].ID = entry2 + 1;
  1160. HostP->Mapping[entry2].ID2 = entry + 1;
  1161. HostP->Mapping[entry].ID2 = entry2 + 1;
  1162. }
  1163. /*
  1164. ** Must set these up, so that utilities show
  1165. ** topology of 16 port RTAs correctly
  1166. */
  1167. for ( link=0; link<LINKS_PER_UNIT; link++ ) {
  1168. HostP->Mapping[entry].Topology[link].Unit = ROUTE_DISCONNECT;
  1169. HostP->Mapping[entry].Topology[link].Link = NO_LINK;
  1170. if (entry2) {
  1171. HostP->Mapping[entry2].Topology[link].Unit = ROUTE_DISCONNECT;
  1172. HostP->Mapping[entry2].Topology[link].Link = NO_LINK;
  1173. }
  1174. }
  1175. }
  1176. #if 0
  1177. /*
  1178. Function: This function is to disable the disk interrupt
  1179. Returns : Nothing
  1180. */
  1181. void
  1182. disable_interrupt(vector)
  1183. int vector;
  1184. {
  1185. int ps;
  1186. int val;
  1187. disable(ps);
  1188. if (vector > 40) {
  1189. val = 1 << (vector - 40);
  1190. __outb(S8259+1, __inb(S8259+1) | val);
  1191. }
  1192. else {
  1193. val = 1 << (vector - 32);
  1194. __outb(M8259+1, __inb(M8259+1) | val);
  1195. }
  1196. restore(ps);
  1197. }
  1198. /*
  1199. Function: This function is to enable the disk interrupt
  1200. Returns : Nothing
  1201. */
  1202. void
  1203. enable_interrupt(vector)
  1204. int vector;
  1205. {
  1206. int ps;
  1207. int val;
  1208. disable(ps);
  1209. if (vector > 40) {
  1210. val = 1 << (vector - 40);
  1211. val = ~val;
  1212. __outb(S8259+1, __inb(S8259+1) & val);
  1213. }
  1214. else {
  1215. val = 1 << (vector - 32);
  1216. val = ~val;
  1217. __outb(M8259+1, __inb(M8259+1) & val);
  1218. }
  1219. restore(ps);
  1220. }
  1221. #endif