riotable.c 30 KB

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