riotable.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:30k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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