riotable.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044
  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 : riotable.c
  24. ** SID : 1.2
  25. ** Last Modified : 11/6/98 10:33:47
  26. ** Retrieved : 11/6/98 10:33:50
  27. **
  28. ** ident @(#)riotable.c 1.2
  29. **
  30. ** -----------------------------------------------------------------------------
  31. */
  32. #ifdef SCCS_LABELS
  33. static char *_riotable_c_sccs_ = "@(#)riotable.c 1.2";
  34. #endif
  35. #include <linux/module.h>
  36. #include <linux/slab.h>
  37. #include <linux/errno.h>
  38. #include <linux/interrupt.h>
  39. #include <linux/string.h>
  40. #include <asm/io.h>
  41. #include <asm/system.h>
  42. #include <asm/string.h>
  43. #include <asm/semaphore.h>
  44. #include <asm/uaccess.h>
  45. #include <linux/termios.h>
  46. #include <linux/serial.h>
  47. #include <linux/generic_serial.h>
  48. #include "linux_compat.h"
  49. #include "rio_linux.h"
  50. #include "typdef.h"
  51. #include "pkt.h"
  52. #include "daemon.h"
  53. #include "rio.h"
  54. #include "riospace.h"
  55. #include "top.h"
  56. #include "cmdpkt.h"
  57. #include "map.h"
  58. #include "riotypes.h"
  59. #include "rup.h"
  60. #include "port.h"
  61. #include "riodrvr.h"
  62. #include "rioinfo.h"
  63. #include "func.h"
  64. #include "errors.h"
  65. #include "pci.h"
  66. #include "parmmap.h"
  67. #include "unixrup.h"
  68. #include "board.h"
  69. #include "host.h"
  70. #include "error.h"
  71. #include "phb.h"
  72. #include "link.h"
  73. #include "cmdblk.h"
  74. #include "route.h"
  75. #include "control.h"
  76. #include "cirrus.h"
  77. #include "rioioctl.h"
  78. #include "param.h"
  79. #include "list.h"
  80. #include "sam.h"
  81. #include "protsts.h"
  82. /*
  83. ** A configuration table has been loaded. It is now up to us
  84. ** to sort it out and use the information contained therein.
  85. */
  86. int
  87. RIONewTable(p)
  88. struct rio_info * p;
  89. {
  90. int Host, Host1, Host2, NameIsUnique, Entry, SubEnt;
  91. struct Map *MapP;
  92. struct Map *HostMapP;
  93. struct Host *HostP;
  94. char *cptr;
  95. /*
  96. ** We have been sent a new table to install. We need to break
  97. ** it down into little bits and spread it around a bit to see
  98. ** what we have got.
  99. */
  100. /*
  101. ** Things to check:
  102. ** (things marked 'xx' aren't checked any more!)
  103. ** (1) That there are no booted Hosts/RTAs out there.
  104. ** (2) That the names are properly formed
  105. ** (3) That blank entries really are.
  106. ** xx (4) That hosts mentioned in the table actually exist. xx
  107. ** (5) That the IDs are unique (per host).
  108. ** (6) That host IDs are zero
  109. ** (7) That port numbers are valid
  110. ** (8) That port numbers aren't duplicated
  111. ** (9) That names aren't duplicated
  112. ** xx (10) That hosts that actually exist are mentioned in the table. xx
  113. */
  114. rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(1)\n");
  115. if ( p->RIOSystemUp ) { /* (1) */
  116. p->RIOError.Error = HOST_HAS_ALREADY_BEEN_BOOTED;
  117. return -EBUSY;
  118. }
  119. p->RIOError.Error = NOTHING_WRONG_AT_ALL;
  120. p->RIOError.Entry = -1;
  121. p->RIOError.Other = -1;
  122. for ( Entry=0; Entry<TOTAL_MAP_ENTRIES; Entry++ ) {
  123. MapP = &p->RIOConnectTable[Entry];
  124. if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) {
  125. rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(2)\n");
  126. cptr = MapP->Name; /* (2) */
  127. cptr[MAX_NAME_LEN-1]='\0';
  128. if ( cptr[0]=='\0' ) {
  129. bcopy(MapP->RtaUniqueNum?"RTA NN":"HOST NN",MapP->Name,8);
  130. MapP->Name[5] = '0'+Entry/10;
  131. MapP->Name[6] = '0'+Entry%10;
  132. }
  133. while ( *cptr ) {
  134. if ( *cptr<' ' || *cptr>'~' ) {
  135. p->RIOError.Error = BAD_CHARACTER_IN_NAME;
  136. p->RIOError.Entry = Entry;
  137. return -ENXIO;
  138. }
  139. cptr++;
  140. }
  141. }
  142. /*
  143. ** If the entry saved was a tentative entry then just forget
  144. ** about it.
  145. */
  146. if ( MapP->Flags & SLOT_TENTATIVE ) {
  147. MapP->HostUniqueNum = 0;
  148. MapP->RtaUniqueNum = 0;
  149. continue;
  150. }
  151. rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(3)\n");
  152. if ( !MapP->RtaUniqueNum && !MapP->HostUniqueNum ) { /* (3) */
  153. if ( MapP->ID || MapP->SysPort || MapP->Flags ) {
  154. rio_dprintk (RIO_DEBUG_TABLE, "%s pretending to be empty but isn't\n",MapP->Name);
  155. p->RIOError.Error = TABLE_ENTRY_ISNT_PROPERLY_NULL;
  156. p->RIOError.Entry = Entry;
  157. return -ENXIO;
  158. }
  159. rio_dprintk (RIO_DEBUG_TABLE, "!RIO: Daemon: test (3) passes\n");
  160. continue;
  161. }
  162. rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(4)\n");
  163. for ( Host=0; Host<p->RIONumHosts; Host++ ) { /* (4) */
  164. if ( p->RIOHosts[Host].UniqueNum==MapP->HostUniqueNum ) {
  165. HostP = &p->RIOHosts[Host];
  166. /*
  167. ** having done the lookup, we don't really want to do
  168. ** it again, so hang the host number in a safe place
  169. */
  170. MapP->Topology[0].Unit = Host;
  171. break;
  172. }
  173. }
  174. if ( Host >= p->RIONumHosts ) {
  175. rio_dprintk (RIO_DEBUG_TABLE, "RTA %s has unknown host unique number 0x%x\n",
  176. MapP->Name, MapP->HostUniqueNum);
  177. MapP->HostUniqueNum = 0;
  178. /* MapP->RtaUniqueNum = 0; */
  179. /* MapP->ID = 0; */
  180. /* MapP->Flags = 0; */
  181. /* MapP->SysPort = 0; */
  182. /* MapP->Name[0] = 0; */
  183. continue;
  184. }
  185. rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(5)\n");
  186. if ( MapP->RtaUniqueNum ) { /* (5) */
  187. if ( !MapP->ID ) {
  188. rio_dprintk (RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an ID of zero!\n",
  189. MapP->Name);
  190. p->RIOError.Error = ZERO_RTA_ID;
  191. p->RIOError.Entry = Entry;
  192. return -ENXIO;
  193. }
  194. if ( MapP->ID > MAX_RUP ) {
  195. rio_dprintk (RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an invalid ID %d\n",
  196. MapP->Name, MapP->ID);
  197. p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
  198. p->RIOError.Entry = Entry;
  199. return -ENXIO;
  200. }
  201. for ( SubEnt=0; SubEnt<Entry; SubEnt++ ) {
  202. if ( MapP->HostUniqueNum ==
  203. p->RIOConnectTable[SubEnt].HostUniqueNum &&
  204. MapP->ID == p->RIOConnectTable[SubEnt].ID ) {
  205. rio_dprintk (RIO_DEBUG_TABLE, "Dupl. ID number allocated to RTA %s and RTA %s\n",
  206. MapP->Name, p->RIOConnectTable[SubEnt].Name);
  207. p->RIOError.Error = DUPLICATED_RTA_ID;
  208. p->RIOError.Entry = Entry;
  209. p->RIOError.Other = SubEnt;
  210. return -ENXIO;
  211. }
  212. /*
  213. ** If the RtaUniqueNum is the same, it may be looking at both
  214. ** entries for a 16 port RTA, so check the ids
  215. */
  216. if ((MapP->RtaUniqueNum ==
  217. p->RIOConnectTable[SubEnt].RtaUniqueNum)
  218. && (MapP->ID2 != p->RIOConnectTable[SubEnt].ID)) {
  219. rio_dprintk (RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n",MapP->Name);
  220. rio_dprintk (RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n",
  221. p->RIOConnectTable[SubEnt].Name);
  222. p->RIOError.Error = DUPLICATE_UNIQUE_NUMBER;
  223. p->RIOError.Entry = Entry;
  224. p->RIOError.Other = SubEnt;
  225. return -ENXIO;
  226. }
  227. }
  228. rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(7a)\n");
  229. /* (7a) */
  230. if ((MapP->SysPort != NO_PORT)&&(MapP->SysPort % PORTS_PER_RTA)) {
  231. rio_dprintk (RIO_DEBUG_TABLE, "TTY Port number %d-RTA %s is not a multiple of %d!\n",
  232. (int)MapP->SysPort,MapP->Name, PORTS_PER_RTA);
  233. p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
  234. p->RIOError.Entry = Entry;
  235. return -ENXIO;
  236. }
  237. rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(7b)\n");
  238. /* (7b) */
  239. if ((MapP->SysPort != NO_PORT)&&(MapP->SysPort >= RIO_PORTS)) {
  240. rio_dprintk (RIO_DEBUG_TABLE, "TTY Port number %d for RTA %s is too big\n",
  241. (int)MapP->SysPort, MapP->Name);
  242. p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
  243. p->RIOError.Entry = Entry;
  244. return -ENXIO;
  245. }
  246. for ( SubEnt=0; SubEnt<Entry; SubEnt++ ) {
  247. if ( p->RIOConnectTable[SubEnt].Flags & RTA16_SECOND_SLOT )
  248. continue;
  249. if ( p->RIOConnectTable[SubEnt].RtaUniqueNum ) {
  250. rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(8)\n");
  251. /* (8) */
  252. if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort ==
  253. p->RIOConnectTable[SubEnt].SysPort) ) {
  254. rio_dprintk (RIO_DEBUG_TABLE, "RTA %s:same TTY port # as RTA %s (%d)\n",
  255. MapP->Name, p->RIOConnectTable[SubEnt].Name,
  256. (int)MapP->SysPort);
  257. p->RIOError.Error = TTY_NUMBER_IN_USE;
  258. p->RIOError.Entry = Entry;
  259. p->RIOError.Other = SubEnt;
  260. return -ENXIO;
  261. }
  262. rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(9)\n");
  263. if (strcmp(MapP->Name,
  264. p->RIOConnectTable[SubEnt].Name)==0 && !(MapP->Flags & RTA16_SECOND_SLOT)) { /* (9) */
  265. rio_dprintk (RIO_DEBUG_TABLE, "RTA name %s used twice\n", MapP->Name);
  266. p->RIOError.Error = NAME_USED_TWICE;
  267. p->RIOError.Entry = Entry;
  268. p->RIOError.Other = SubEnt;
  269. return -ENXIO;
  270. }
  271. }
  272. }
  273. }
  274. else { /* (6) */
  275. rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(6)\n");
  276. if ( MapP->ID ) {
  277. rio_dprintk (RIO_DEBUG_TABLE, "RIO:HOST %s has been allocated ID that isn't zero!\n",
  278. MapP->Name);
  279. p->RIOError.Error = HOST_ID_NOT_ZERO;
  280. p->RIOError.Entry = Entry;
  281. return -ENXIO;
  282. }
  283. if ( MapP->SysPort != NO_PORT ) {
  284. rio_dprintk (RIO_DEBUG_TABLE, "RIO: HOST %s has been allocated port numbers!\n",
  285. MapP->Name);
  286. p->RIOError.Error = HOST_SYSPORT_BAD;
  287. p->RIOError.Entry = Entry;
  288. return -ENXIO;
  289. }
  290. }
  291. }
  292. /*
  293. ** wow! if we get here then it's a goody!
  294. */
  295. /*
  296. ** Zero the (old) entries for each host...
  297. */
  298. for ( Host=0; Host<RIO_HOSTS; Host++ ) {
  299. for ( Entry=0; Entry<MAX_RUP; Entry++ ) {
  300. bzero((caddr_t)&p->RIOHosts[Host].Mapping[Entry],
  301. sizeof(struct Map));
  302. }
  303. bzero((caddr_t)&p->RIOHosts[Host].Name[0],
  304. sizeof(p->RIOHosts[Host].Name) );
  305. }
  306. /*
  307. ** Copy in the new table entries
  308. */
  309. for ( Entry=0; Entry< TOTAL_MAP_ENTRIES; Entry++ ) {
  310. rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: Copy table for Host entry %d\n", Entry);
  311. MapP = &p->RIOConnectTable[Entry];
  312. /*
  313. ** Now, if it is an empty slot ignore it!
  314. */
  315. if ( MapP->HostUniqueNum==0 )
  316. continue;
  317. /*
  318. ** we saved the host number earlier, so grab it back
  319. */
  320. HostP = &p->RIOHosts[MapP->Topology[0].Unit];
  321. /*
  322. ** If it is a host, then we only need to fill in the name field.
  323. */
  324. if ( MapP->ID==0 ) {
  325. rio_dprintk (RIO_DEBUG_TABLE, "Host entry found. Name %s\n", MapP->Name);
  326. bcopy(MapP->Name,HostP->Name,MAX_NAME_LEN);
  327. continue;
  328. }
  329. /*
  330. ** Its an RTA entry, so fill in the host mapping entries for it
  331. ** and the port mapping entries. Notice that entry zero is for
  332. ** ID one.
  333. */
  334. HostMapP = &HostP->Mapping[MapP->ID-1];
  335. if (MapP->Flags & SLOT_IN_USE) {
  336. rio_dprintk (RIO_DEBUG_TABLE, "Rta entry found. Name %s\n", MapP->Name);
  337. /*
  338. ** structure assign, then sort out the bits we shouldn't have done
  339. */
  340. *HostMapP = *MapP;
  341. HostMapP->Flags = SLOT_IN_USE;
  342. if (MapP->Flags & RTA16_SECOND_SLOT)
  343. HostMapP->Flags |= RTA16_SECOND_SLOT;
  344. RIOReMapPorts(p, HostP, HostMapP );
  345. }
  346. else {
  347. rio_dprintk (RIO_DEBUG_TABLE, "TENTATIVE Rta entry found. Name %s\n", MapP->Name);
  348. }
  349. }
  350. for ( Entry=0; Entry< TOTAL_MAP_ENTRIES; Entry++ ) {
  351. p->RIOSavedTable[Entry] = p->RIOConnectTable[Entry];
  352. }
  353. for ( Host=0; Host<p->RIONumHosts; Host++ ) {
  354. for ( SubEnt=0; SubEnt<LINKS_PER_UNIT; SubEnt++ ) {
  355. p->RIOHosts[Host].Topology[SubEnt].Unit = ROUTE_DISCONNECT;
  356. p->RIOHosts[Host].Topology[SubEnt].Link = NO_LINK;
  357. }
  358. for ( Entry=0; Entry<MAX_RUP; Entry++ ) {
  359. for ( SubEnt=0; SubEnt<LINKS_PER_UNIT; SubEnt++ ) {
  360. p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Unit =
  361. ROUTE_DISCONNECT;
  362. p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Link =
  363. NO_LINK;
  364. }
  365. }
  366. if ( !p->RIOHosts[Host].Name[0] ) {
  367. bcopy("HOST 1",p->RIOHosts[Host].Name,7);
  368. p->RIOHosts[Host].Name[5] += Host;
  369. }
  370. /*
  371. ** Check that default name assigned is unique.
  372. */
  373. Host1 = Host;
  374. NameIsUnique = 0;
  375. while (!NameIsUnique) {
  376. NameIsUnique = 1;
  377. for ( Host2=0; Host2<p->RIONumHosts; Host2++ ) {
  378. if (Host2 == Host)
  379. continue;
  380. if (strcmp(p->RIOHosts[Host].Name, p->RIOHosts[Host2].Name)
  381. == 0) {
  382. NameIsUnique = 0;
  383. Host1++;
  384. if (Host1 >= p->RIONumHosts)
  385. Host1 = 0;
  386. p->RIOHosts[Host].Name[5] = '1' + Host1;
  387. }
  388. }
  389. }
  390. /*
  391. ** Rename host if name already used.
  392. */
  393. if (Host1 != Host)
  394. {
  395. rio_dprintk (RIO_DEBUG_TABLE, "Default name %s already used\n", p->RIOHosts[Host].Name);
  396. bcopy("HOST 1",p->RIOHosts[Host].Name,7);
  397. p->RIOHosts[Host].Name[5] += Host1;
  398. }
  399. rio_dprintk (RIO_DEBUG_TABLE, "Assigning default name %s\n", p->RIOHosts[Host].Name);
  400. }
  401. return 0;
  402. }
  403. /*
  404. ** User process needs the config table - build it from first
  405. ** principles.
  406. */
  407. int
  408. RIOApel(p)
  409. struct rio_info * p;
  410. {
  411. int Host;
  412. int link;
  413. int Rup;
  414. int Next = 0;
  415. struct Map *MapP;
  416. struct Host *HostP;
  417. long oldspl;
  418. disable(oldspl); /* strange but true! */
  419. rio_dprintk (RIO_DEBUG_TABLE, "Generating a table to return to config.rio\n");
  420. bzero((caddr_t)&p->RIOConnectTable[0],
  421. sizeof(struct Map) * TOTAL_MAP_ENTRIES );
  422. for ( Host=0; Host<RIO_HOSTS; Host++ ) {
  423. rio_dprintk (RIO_DEBUG_TABLE, "Processing host %d\n", Host);
  424. HostP = &p->RIOHosts[Host];
  425. MapP = &p->RIOConnectTable[Next++];
  426. MapP->HostUniqueNum = HostP->UniqueNum;
  427. if ( (HostP->Flags & RUN_STATE) != RC_RUNNING )
  428. continue;
  429. MapP->RtaUniqueNum = 0;
  430. MapP->ID = 0;
  431. MapP->Flags = SLOT_IN_USE;
  432. MapP->SysPort = NO_PORT;
  433. for ( link=0; link<LINKS_PER_UNIT; link++ )
  434. MapP->Topology[link] = HostP->Topology[link];
  435. bcopy(HostP->Name,MapP->Name,MAX_NAME_LEN);
  436. for ( Rup=0; Rup<MAX_RUP; Rup++ ) {
  437. if ( HostP->Mapping[Rup].Flags & (SLOT_IN_USE|SLOT_TENTATIVE) ) {
  438. p->RIOConnectTable[Next] = HostP->Mapping[Rup];
  439. if ( HostP->Mapping[Rup].Flags & SLOT_IN_USE)
  440. p->RIOConnectTable[Next].Flags |= SLOT_IN_USE;
  441. if ( HostP->Mapping[Rup].Flags & SLOT_TENTATIVE)
  442. p->RIOConnectTable[Next].Flags |= SLOT_TENTATIVE;
  443. if ( HostP->Mapping[Rup].Flags & RTA16_SECOND_SLOT )
  444. p->RIOConnectTable[Next].Flags |= RTA16_SECOND_SLOT;
  445. Next++;
  446. }
  447. }
  448. }
  449. restore(oldspl);
  450. return 0;
  451. }
  452. /*
  453. ** config.rio has taken a dislike to one of the gross maps entries.
  454. ** if the entry is suitably inactive, then we can gob on it and remove
  455. ** it from the table.
  456. */
  457. int
  458. RIODeleteRta(p, MapP)
  459. struct rio_info *p;
  460. struct Map *MapP;
  461. {
  462. int host, entry, port, link;
  463. int SysPort;
  464. struct Host *HostP;
  465. struct Map *HostMapP;
  466. struct Port *PortP;
  467. int work_done = 0;
  468. unsigned long lock_flags, sem_flags;
  469. rio_dprintk (RIO_DEBUG_TABLE, "Delete entry on host %x, rta %x\n",
  470. MapP->HostUniqueNum, MapP->RtaUniqueNum);
  471. for ( host=0; host < p->RIONumHosts; host++ ) {
  472. HostP = &p->RIOHosts[host];
  473. rio_spin_lock_irqsave( &HostP->HostLock, lock_flags );
  474. if ( (HostP->Flags & RUN_STATE) != RC_RUNNING ) {
  475. rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags);
  476. continue;
  477. }
  478. for ( entry=0; entry<MAX_RUP; entry++ ) {
  479. if ( MapP->RtaUniqueNum == HostP->Mapping[entry].RtaUniqueNum ) {
  480. HostMapP = &HostP->Mapping[entry];
  481. rio_dprintk (RIO_DEBUG_TABLE, "Found entry offset %d on host %s\n",
  482. entry, HostP->Name);
  483. /*
  484. ** Check all four links of the unit are disconnected
  485. */
  486. for ( link=0; link< LINKS_PER_UNIT; link++ ) {
  487. if ( HostMapP->Topology[link].Unit != ROUTE_DISCONNECT ) {
  488. rio_dprintk (RIO_DEBUG_TABLE, "Entry is in use and cannot be deleted!\n");
  489. p->RIOError.Error = UNIT_IS_IN_USE;
  490. rio_spin_unlock_irqrestore( &HostP->HostLock, lock_flags);
  491. return -EBUSY;
  492. }
  493. }
  494. /*
  495. ** Slot has been allocated, BUT not booted/routed/
  496. ** connected/selected or anything else-ed
  497. */
  498. SysPort = HostMapP->SysPort;
  499. if ( SysPort != NO_PORT ) {
  500. for (port=SysPort; port < SysPort+PORTS_PER_RTA; port++) {
  501. PortP = p->RIOPortp[port];
  502. rio_dprintk (RIO_DEBUG_TABLE, "Unmap port\n");
  503. rio_spin_lock_irqsave( &PortP->portSem, sem_flags );
  504. PortP->Mapped = 0;
  505. if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) ) {
  506. rio_dprintk (RIO_DEBUG_TABLE, "Gob on port\n");
  507. PortP->TxBufferIn = PortP->TxBufferOut = 0;
  508. /* What should I do
  509. wakeup( &PortP->TxBufferIn );
  510. wakeup( &PortP->TxBufferOut);
  511. */
  512. PortP->InUse = NOT_INUSE;
  513. /* What should I do
  514. wakeup( &PortP->InUse );
  515. signal(PortP->TtyP->t_pgrp,SIGKILL);
  516. ttyflush(PortP->TtyP,(FREAD|FWRITE));
  517. */
  518. PortP->State |= RIO_CLOSING | RIO_DELETED;
  519. }
  520. /*
  521. ** For the second slot of a 16 port RTA, the
  522. ** driver needs to reset the changes made to
  523. ** the phb to port mappings in RIORouteRup.
  524. */
  525. if (PortP->SecondBlock) {
  526. ushort dest_unit = HostMapP->ID;
  527. ushort dest_port = port - SysPort;
  528. WORD *TxPktP;
  529. PKT *Pkt;
  530. for (TxPktP = PortP->TxStart;
  531. TxPktP <= PortP->TxEnd; TxPktP++) {
  532. /*
  533. ** *TxPktP is the pointer to the
  534. ** transmit packet on the host card.
  535. ** This needs to be translated into
  536. ** a 32 bit pointer so it can be
  537. ** accessed from the driver.
  538. */
  539. Pkt = (PKT *) RIO_PTR(HostP->Caddr,
  540. RWORD(*TxPktP));
  541. rio_dprintk (RIO_DEBUG_TABLE,
  542. "Tx packet (%x) destination: Old %x:%x New %x:%x\n",
  543. *TxPktP, Pkt->dest_unit,
  544. Pkt->dest_port, dest_unit, dest_port);
  545. WWORD(Pkt->dest_unit, dest_unit);
  546. WWORD(Pkt->dest_port, dest_port);
  547. }
  548. rio_dprintk (RIO_DEBUG_TABLE,
  549. "Port %d phb destination: Old %x:%x New %x:%x\n",
  550. port, PortP->PhbP->destination & 0xff,
  551. (PortP->PhbP->destination >> 8) & 0xff,
  552. dest_unit, dest_port);
  553. WWORD(PortP->PhbP->destination,
  554. dest_unit + (dest_port << 8));
  555. }
  556. rio_spin_unlock_irqrestore(&PortP->portSem, sem_flags);
  557. }
  558. }
  559. rio_dprintk (RIO_DEBUG_TABLE, "Entry nulled.\n");
  560. bzero((char *)HostMapP,sizeof(struct Map));
  561. work_done++;
  562. }
  563. }
  564. rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags);
  565. }
  566. /* XXXXX lock me up */
  567. for ( entry=0; entry< TOTAL_MAP_ENTRIES; entry++ ) {
  568. if ( p->RIOSavedTable[entry].RtaUniqueNum == MapP->RtaUniqueNum ) {
  569. bzero((char *)&p->RIOSavedTable[entry],sizeof(struct Map));
  570. work_done++;
  571. }
  572. if ( p->RIOConnectTable[entry].RtaUniqueNum == MapP->RtaUniqueNum ) {
  573. bzero((char *)&p->RIOConnectTable[entry],sizeof(struct Map));
  574. work_done++;
  575. }
  576. }
  577. if ( work_done )
  578. return 0;
  579. rio_dprintk (RIO_DEBUG_TABLE, "Couldn't find entry to be deleted\n");
  580. p->RIOError.Error = COULDNT_FIND_ENTRY;
  581. return -ENXIO;
  582. }
  583. int RIOAssignRta( struct rio_info *p, struct Map *MapP )
  584. {
  585. int host;
  586. struct Map *HostMapP;
  587. char *sptr;
  588. int link;
  589. rio_dprintk (RIO_DEBUG_TABLE, "Assign entry on host %x, rta %x, ID %d, Sysport %d\n",
  590. MapP->HostUniqueNum,MapP->RtaUniqueNum,
  591. MapP->ID, (int)MapP->SysPort);
  592. if ((MapP->ID != (ushort)-1) &&
  593. ((int)MapP->ID < (int)1 || (int)MapP->ID > MAX_RUP ))
  594. {
  595. rio_dprintk (RIO_DEBUG_TABLE, "Bad ID in map entry!\n");
  596. p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
  597. return -EINVAL;
  598. }
  599. if (MapP->RtaUniqueNum == 0)
  600. {
  601. rio_dprintk (RIO_DEBUG_TABLE, "Rta Unique number zero!\n");
  602. p->RIOError.Error = RTA_UNIQUE_NUMBER_ZERO;
  603. return -EINVAL;
  604. }
  605. if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA) )
  606. {
  607. rio_dprintk (RIO_DEBUG_TABLE, "Port %d not multiple of %d!\n",(int)MapP->SysPort,PORTS_PER_RTA);
  608. p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
  609. return -EINVAL;
  610. }
  611. if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS) )
  612. {
  613. rio_dprintk (RIO_DEBUG_TABLE, "Port %d not valid!\n",(int)MapP->SysPort);
  614. p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
  615. return -EINVAL;
  616. }
  617. /*
  618. ** Copy the name across to the map entry.
  619. */
  620. MapP->Name[MAX_NAME_LEN-1] = '\0';
  621. sptr = MapP->Name;
  622. while ( *sptr )
  623. {
  624. if ( *sptr<' ' || *sptr>'~' )
  625. {
  626. rio_dprintk (RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n");
  627. p->RIOError.Error = BAD_CHARACTER_IN_NAME;
  628. return -EINVAL;
  629. }
  630. sptr++;
  631. }
  632. for ( host=0; host < p->RIONumHosts; host++ )
  633. {
  634. if ( MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum )
  635. {
  636. if ( (p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING )
  637. {
  638. p->RIOError.Error = HOST_NOT_RUNNING;
  639. return -ENXIO;
  640. }
  641. /*
  642. ** Now we have a host we need to allocate an ID
  643. ** if the entry does not already have one.
  644. */
  645. if (MapP->ID == (ushort)-1)
  646. {
  647. int nNewID;
  648. rio_dprintk (RIO_DEBUG_TABLE, "Attempting to get a new ID for rta \"%s\"\n",
  649. MapP->Name);
  650. /*
  651. ** The idea here is to allow RTA's to be assigned
  652. ** before they actually appear on the network.
  653. ** This allows the addition of RTA's without having
  654. ** to plug them in.
  655. ** What we do is:
  656. ** - Find a free ID and allocate it to the RTA.
  657. ** - If this map entry is the second half of a
  658. ** 16 port entry then find the other half and
  659. ** make sure the 2 cross reference each other.
  660. */
  661. if (RIOFindFreeID(p, &p->RIOHosts[host], &nNewID, NULL) != 0)
  662. {
  663. p->RIOError.Error = COULDNT_FIND_ENTRY;
  664. return -EBUSY;
  665. }
  666. MapP->ID = (ushort)nNewID + 1;
  667. rio_dprintk (RIO_DEBUG_TABLE, "Allocated ID %d for this new RTA.\n", MapP->ID);
  668. HostMapP = &p->RIOHosts[host].Mapping[nNewID];
  669. HostMapP->RtaUniqueNum = MapP->RtaUniqueNum;
  670. HostMapP->HostUniqueNum = MapP->HostUniqueNum;
  671. HostMapP->ID = MapP->ID;
  672. for (link = 0; link < LINKS_PER_UNIT; link++)
  673. {
  674. HostMapP->Topology[link].Unit = ROUTE_DISCONNECT;
  675. HostMapP->Topology[link].Link = NO_LINK;
  676. }
  677. if (MapP->Flags & RTA16_SECOND_SLOT)
  678. {
  679. int unit;
  680. for (unit = 0; unit < MAX_RUP; unit++)
  681. if (p->RIOHosts[host].Mapping[unit].RtaUniqueNum ==
  682. MapP->RtaUniqueNum)
  683. break;
  684. if (unit == MAX_RUP)
  685. {
  686. p->RIOError.Error = COULDNT_FIND_ENTRY;
  687. return -EBUSY;
  688. }
  689. HostMapP->Flags |= RTA16_SECOND_SLOT;
  690. HostMapP->ID2 = MapP->ID2 = p->RIOHosts[host].Mapping[unit].ID;
  691. p->RIOHosts[host].Mapping[unit].ID2 = MapP->ID;
  692. rio_dprintk (RIO_DEBUG_TABLE, "Cross referenced id %d to ID %d.\n",
  693. MapP->ID,
  694. p->RIOHosts[host].Mapping[unit].ID);
  695. }
  696. }
  697. HostMapP = &p->RIOHosts[host].Mapping[MapP->ID-1];
  698. if ( HostMapP->Flags & SLOT_IN_USE )
  699. {
  700. rio_dprintk (RIO_DEBUG_TABLE, "Map table slot for ID %d is already in use.\n", MapP->ID);
  701. p->RIOError.Error = ID_ALREADY_IN_USE;
  702. return -EBUSY;
  703. }
  704. /*
  705. ** Assign the sys ports and the name, and mark the slot as
  706. ** being in use.
  707. */
  708. HostMapP->SysPort = MapP->SysPort;
  709. if ((MapP->Flags & RTA16_SECOND_SLOT) == 0)
  710. CCOPY( MapP->Name, HostMapP->Name, MAX_NAME_LEN );
  711. HostMapP->Flags = SLOT_IN_USE | RTA_BOOTED;
  712. #ifdef NEED_TO_FIX
  713. RIO_SV_BROADCAST(p->RIOHosts[host].svFlags[MapP->ID-1]);
  714. #endif
  715. if (MapP->Flags & RTA16_SECOND_SLOT)
  716. HostMapP->Flags |= RTA16_SECOND_SLOT;
  717. RIOReMapPorts( p, &p->RIOHosts[host], HostMapP );
  718. /*
  719. ** Adjust 2nd block of 8 phbs
  720. */
  721. if (MapP->Flags & RTA16_SECOND_SLOT)
  722. RIOFixPhbs(p, &p->RIOHosts[host], HostMapP->ID - 1);
  723. if ( HostMapP->SysPort != NO_PORT )
  724. {
  725. if ( HostMapP->SysPort < p->RIOFirstPortsBooted )
  726. p->RIOFirstPortsBooted = HostMapP->SysPort;
  727. if ( HostMapP->SysPort > p->RIOLastPortsBooted )
  728. p->RIOLastPortsBooted = HostMapP->SysPort;
  729. }
  730. if (MapP->Flags & RTA16_SECOND_SLOT)
  731. rio_dprintk (RIO_DEBUG_TABLE, "Second map of RTA %s added to configuration\n",
  732. p->RIOHosts[host].Mapping[MapP->ID2 - 1].Name);
  733. else
  734. rio_dprintk (RIO_DEBUG_TABLE, "RTA %s added to configuration\n", MapP->Name);
  735. return 0;
  736. }
  737. }
  738. p->RIOError.Error = UNKNOWN_HOST_NUMBER;
  739. rio_dprintk (RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum);
  740. return -ENXIO;
  741. }
  742. int
  743. RIOReMapPorts(p, HostP, HostMapP)
  744. struct rio_info * p;
  745. struct Host *HostP;
  746. struct Map *HostMapP;
  747. {
  748. register struct Port *PortP;
  749. uint SubEnt;
  750. uint HostPort;
  751. uint SysPort;
  752. ushort RtaType;
  753. unsigned long flags;
  754. #ifdef CHECK
  755. CheckHostP( HostP );
  756. CheckHostMapP( HostMapP );
  757. #endif
  758. rio_dprintk (RIO_DEBUG_TABLE, "Mapping sysport %d to id %d\n", (int)HostMapP->SysPort, HostMapP->ID);
  759. /*
  760. ** We need to tell the UnixRups which sysport the rup corresponds to
  761. */
  762. HostP->UnixRups[HostMapP->ID-1].BaseSysPort = HostMapP->SysPort;
  763. if ( HostMapP->SysPort == NO_PORT )
  764. return(0);
  765. RtaType = GetUnitType(HostMapP->RtaUniqueNum);
  766. rio_dprintk (RIO_DEBUG_TABLE, "Mapping sysport %d-%d\n",
  767. (int)HostMapP->SysPort, (int)HostMapP->SysPort+PORTS_PER_RTA-1);
  768. /*
  769. ** now map each of its eight ports
  770. */
  771. for ( SubEnt=0; SubEnt<PORTS_PER_RTA; SubEnt++) {
  772. rio_dprintk (RIO_DEBUG_TABLE, "subent = %d, HostMapP->SysPort = %d\n",
  773. SubEnt, (int)HostMapP->SysPort);
  774. SysPort = HostMapP->SysPort+SubEnt; /* portnumber within system */
  775. /* portnumber on host */
  776. HostPort = (HostMapP->ID-1)*PORTS_PER_RTA+SubEnt;
  777. rio_dprintk (RIO_DEBUG_TABLE, "c1 p = %p, p->rioPortp = %p\n", p, p->RIOPortp);
  778. PortP = p->RIOPortp[SysPort];
  779. #if 0
  780. PortP->TtyP = &p->channel[SysPort];
  781. #endif
  782. rio_dprintk (RIO_DEBUG_TABLE, "Map port\n");
  783. /*
  784. ** Point at all the real neat data structures
  785. */
  786. rio_spin_lock_irqsave(&PortP->portSem, flags);
  787. PortP->HostP = HostP;
  788. PortP->Caddr = HostP->Caddr;
  789. /*
  790. ** The PhbP cannot be filled in yet
  791. ** unless the host has been booted
  792. */
  793. if ((HostP->Flags & RUN_STATE) == RC_RUNNING) {
  794. struct PHB *PhbP = PortP->PhbP = &HostP->PhbP[HostPort];
  795. PortP->TxAdd =(WORD *)RIO_PTR(HostP->Caddr,RWORD(PhbP->tx_add));
  796. PortP->TxStart =(WORD *)RIO_PTR(HostP->Caddr,RWORD(PhbP->tx_start));
  797. PortP->TxEnd =(WORD *)RIO_PTR(HostP->Caddr,RWORD(PhbP->tx_end));
  798. PortP->RxRemove=(WORD *)RIO_PTR(HostP->Caddr,
  799. RWORD(PhbP->rx_remove));
  800. PortP->RxStart =(WORD *)RIO_PTR(HostP->Caddr,RWORD(PhbP->rx_start));
  801. PortP->RxEnd =(WORD *)RIO_PTR(HostP->Caddr,RWORD(PhbP->rx_end));
  802. }
  803. else
  804. PortP->PhbP = NULL;
  805. /*
  806. ** port related flags
  807. */
  808. PortP->HostPort = HostPort;
  809. /*
  810. ** For each part of a 16 port RTA, RupNum is ID - 1.
  811. */
  812. PortP->RupNum = HostMapP->ID - 1;
  813. if (HostMapP->Flags & RTA16_SECOND_SLOT) {
  814. PortP->ID2 = HostMapP->ID2 - 1;
  815. PortP->SecondBlock = TRUE;
  816. }
  817. else {
  818. PortP->ID2 = 0;
  819. PortP->SecondBlock = FALSE;
  820. }
  821. PortP->RtaUniqueNum = HostMapP->RtaUniqueNum;
  822. /*
  823. ** If the port was already mapped then thats all we need to do.
  824. */
  825. if (PortP->Mapped) {
  826. rio_spin_unlock_irqrestore( &PortP->portSem, flags);
  827. continue;
  828. }
  829. else HostMapP->Flags &= ~RTA_NEWBOOT;
  830. PortP->State = 0;
  831. PortP->Config = 0;
  832. /*
  833. ** Check out the module type - if it is special (read only etc.)
  834. ** then we need to set flags in the PortP->Config.
  835. ** Note: For 16 port RTA, all ports are of the same type.
  836. */
  837. if (RtaType == TYPE_RTA16) {
  838. PortP->Config |= p->RIOModuleTypes[HostP->UnixRups
  839. [HostMapP->ID-1].ModTypes].Flags[SubEnt % PORTS_PER_MODULE];
  840. } else {
  841. if ( SubEnt < PORTS_PER_MODULE )
  842. PortP->Config |= p->RIOModuleTypes[LONYBLE(HostP->UnixRups
  843. [HostMapP->ID-1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE];
  844. else
  845. PortP->Config |= p->RIOModuleTypes[HINYBLE(HostP->UnixRups
  846. [HostMapP->ID-1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE];
  847. }
  848. /*
  849. ** more port related flags
  850. */
  851. PortP->PortState = 0;
  852. PortP->ModemLines = 0;
  853. PortP->ModemState = 0;
  854. PortP->CookMode = COOK_WELL;
  855. PortP->ParamSem = 0;
  856. PortP->FlushCmdBodge= 0;
  857. PortP->WflushFlag = 0;
  858. PortP->MagicFlags = 0;
  859. PortP->Lock = 0;
  860. PortP->Store = 0;
  861. PortP->FirstOpen = 1;
  862. /*
  863. ** Buffers 'n things
  864. */
  865. PortP->RxDataStart = 0;
  866. PortP->Cor2Copy = 0;
  867. PortP->Name = &HostMapP->Name[0];
  868. #ifdef STATS
  869. bzero( (caddr_t)&PortP->Stat, sizeof(struct RIOStats) );
  870. #endif
  871. PortP->statsGather = 0;
  872. PortP->txchars = 0;
  873. PortP->rxchars = 0;
  874. PortP->opens = 0;
  875. PortP->closes = 0;
  876. PortP->ioctls = 0;
  877. if ( PortP->TxRingBuffer )
  878. bzero( PortP->TxRingBuffer, p->RIOBufferSize );
  879. else if ( p->RIOBufferSize ) {
  880. PortP->TxRingBuffer = sysbrk(p->RIOBufferSize);
  881. bzero( PortP->TxRingBuffer, p->RIOBufferSize );
  882. }
  883. PortP->TxBufferOut = 0;
  884. PortP->TxBufferIn = 0;
  885. PortP->Debug = 0;
  886. /*
  887. ** LastRxTgl stores the state of the rx toggle bit for this
  888. ** port, to be compared with the state of the next pkt received.
  889. ** If the same, we have received the same rx pkt from the RTA
  890. ** twice. Initialise to a value not equal to PHB_RX_TGL or 0.
  891. */
  892. PortP->LastRxTgl = ~(uchar)PHB_RX_TGL;
  893. /*
  894. ** and mark the port as usable
  895. */
  896. PortP->Mapped = 1;
  897. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  898. }
  899. if ( HostMapP->SysPort < p->RIOFirstPortsMapped )
  900. p->RIOFirstPortsMapped = HostMapP->SysPort;
  901. if ( HostMapP->SysPort > p->RIOLastPortsMapped )
  902. p->RIOLastPortsMapped = HostMapP->SysPort;
  903. return 0;
  904. }
  905. int
  906. RIOChangeName(p, MapP)
  907. struct rio_info *p;
  908. struct Map* MapP;
  909. {
  910. int host;
  911. struct Map *HostMapP;
  912. char *sptr;
  913. rio_dprintk (RIO_DEBUG_TABLE, "Change name entry on host %x, rta %x, ID %d, Sysport %d\n",
  914. MapP->HostUniqueNum,MapP->RtaUniqueNum,
  915. MapP->ID, (int)MapP->SysPort);
  916. if ( MapP->ID > MAX_RUP ) {
  917. rio_dprintk (RIO_DEBUG_TABLE, "Bad ID in map entry!\n");
  918. p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
  919. return -EINVAL;
  920. }
  921. MapP->Name[MAX_NAME_LEN-1] = '\0';
  922. sptr = MapP->Name;
  923. while ( *sptr ) {
  924. if ( *sptr<' ' || *sptr>'~' ) {
  925. rio_dprintk (RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n");
  926. p->RIOError.Error = BAD_CHARACTER_IN_NAME;
  927. return -EINVAL;
  928. }
  929. sptr++;
  930. }
  931. for ( host=0; host < p->RIONumHosts; host++ ) {
  932. if ( MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum ) {
  933. if ( (p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING ) {
  934. p->RIOError.Error = HOST_NOT_RUNNING;
  935. return -ENXIO;
  936. }
  937. if ( MapP->ID==0 ) {
  938. CCOPY( MapP->Name, p->RIOHosts[host].Name, MAX_NAME_LEN );
  939. return 0;
  940. }
  941. HostMapP = &p->RIOHosts[host].Mapping[MapP->ID-1];
  942. if ( HostMapP->RtaUniqueNum != MapP->RtaUniqueNum ) {
  943. p->RIOError.Error = RTA_NUMBER_WRONG;
  944. return -ENXIO;
  945. }
  946. CCOPY( MapP->Name, HostMapP->Name, MAX_NAME_LEN );
  947. return 0;
  948. }
  949. }
  950. p->RIOError.Error = UNKNOWN_HOST_NUMBER;
  951. rio_dprintk (RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum);
  952. return -ENXIO;
  953. }