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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2. ** -----------------------------------------------------------------------------
  3. **
  4. **  Perle Specialix driver for Linux
  5. **  ported from the existing SCO driver source
  6. **
  7.  *
  8.  *  (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
  9.  *
  10.  *      This program is free software; you can redistribute it and/or modify
  11.  *      it under the terms of the GNU General Public License as published by
  12.  *      the Free Software Foundation; either version 2 of the License, or
  13.  *      (at your option) any later version.
  14.  *
  15.  *      This program is distributed in the hope that it will be useful,
  16.  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *      GNU General Public License for more details.
  19.  *
  20.  *      You should have received a copy of the GNU General Public License
  21.  *      along with this program; if not, write to the Free Software
  22.  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23. **
  24. ** Module : riocmd.c
  25. ** SID : 1.2
  26. ** Last Modified : 11/6/98 10:33:41
  27. ** Retrieved : 11/6/98 10:33:49
  28. **
  29. **  ident @(#)riocmd.c 1.2
  30. **
  31. ** -----------------------------------------------------------------------------
  32. */
  33. #ifdef SCCS_LABELS
  34. static char *_riocmd_c_sccs_ = "@(#)riocmd.c 1.2";
  35. #endif
  36. #define __NO_VERSION__
  37. #include <linux/module.h>
  38. #include <linux/slab.h>
  39. #include <linux/errno.h>
  40. #include <linux/tty.h>
  41. #include <asm/io.h>
  42. #include <asm/system.h>
  43. #include <asm/string.h>
  44. #include <asm/semaphore.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. static struct IdentifyRta IdRta;
  79. static struct KillNeighbour KillUnit;
  80. int
  81. RIOFoadRta(HostP, MapP)
  82. struct Host * HostP;
  83. struct Map * MapP;
  84. {
  85. struct CmdBlk *CmdBlkP;
  86. rio_dprintk (RIO_DEBUG_CMD, "FOAD RTAn");
  87. CmdBlkP = RIOGetCmdBlk();
  88. if ( !CmdBlkP ) {
  89. rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: GetCmdBlk failedn");
  90. return ENXIO;
  91. }
  92. CmdBlkP->Packet.dest_unit = MapP->ID;
  93. CmdBlkP->Packet.dest_port = BOOT_RUP;
  94. CmdBlkP->Packet.src_unit  = 0;
  95. CmdBlkP->Packet.src_port  = BOOT_RUP;
  96. CmdBlkP->Packet.len    = 0x84;
  97. CmdBlkP->Packet.data[0]   = IFOAD;
  98. CmdBlkP->Packet.data[1]   = 0;
  99. CmdBlkP->Packet.data[2]   = IFOAD_MAGIC & 0xFF;
  100. CmdBlkP->Packet.data[3]   = (IFOAD_MAGIC >> 8) & 0xFF;
  101. if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
  102. rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: Failed to queue foad commandn");
  103. return EIO;
  104. }
  105. return 0;
  106. }
  107. int
  108. RIOZombieRta(HostP, MapP)
  109. struct Host * HostP;
  110. struct Map * MapP;
  111. {
  112. struct CmdBlk *CmdBlkP;
  113. rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTAn");
  114. CmdBlkP = RIOGetCmdBlk();
  115. if ( !CmdBlkP ) {
  116. rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: GetCmdBlk failedn");
  117. return ENXIO;
  118. }
  119. CmdBlkP->Packet.dest_unit = MapP->ID;
  120. CmdBlkP->Packet.dest_port = BOOT_RUP;
  121. CmdBlkP->Packet.src_unit  = 0;
  122. CmdBlkP->Packet.src_port  = BOOT_RUP;
  123. CmdBlkP->Packet.len    = 0x84;
  124. CmdBlkP->Packet.data[0]   = ZOMBIE;
  125. CmdBlkP->Packet.data[1]   = 0;
  126. CmdBlkP->Packet.data[2]   = ZOMBIE_MAGIC & 0xFF;
  127. CmdBlkP->Packet.data[3]   = (ZOMBIE_MAGIC >> 8) & 0xFF;
  128. if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
  129. rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: Failed to queue zombie commandn");
  130. return EIO;
  131. }
  132. return 0;
  133. }
  134. int
  135. RIOCommandRta(p, RtaUnique, func)
  136. struct rio_info * p;
  137. uint RtaUnique;
  138. int (* func)( struct Host *HostP, struct Map *MapP );
  139. {
  140. uint Host;
  141. rio_dprintk (RIO_DEBUG_CMD, "Command RTA 0x%x func 0x%xn", RtaUnique, (int)func);
  142. if ( !RtaUnique )
  143. return(0);
  144. for ( Host = 0; Host < p->RIONumHosts; Host++ ) {
  145. uint Rta;
  146. struct Host *HostP = &p->RIOHosts[Host];
  147. for ( Rta = 0; Rta < RTAS_PER_HOST; Rta++ ) {
  148. struct Map *MapP = &HostP->Mapping[Rta];
  149. if ( MapP->RtaUniqueNum == RtaUnique ) {
  150. uint Link;
  151. /*
  152. ** now, lets just check we have a route to it...
  153. ** IF the routing stuff is working, then one of the
  154. ** topology entries for this unit will have a legit
  155. ** route *somewhere*. We care not where - if its got
  156. ** any connections, we can get to it.
  157. */
  158. for ( Link = 0; Link < LINKS_PER_UNIT; Link++ ) {
  159. if ( MapP->Topology[Link].Unit <= (uchar)MAX_RUP ) {
  160. /*
  161. ** Its worth trying the operation...
  162. */
  163. return (*func)( HostP, MapP );
  164. }
  165. }
  166. }
  167. }
  168. }
  169. return ENXIO;
  170. }
  171. int
  172. RIOIdentifyRta(p, arg)
  173. struct rio_info * p;
  174. caddr_t arg;
  175. {
  176. uint Host;
  177. if ( copyin( (int)arg, (caddr_t)&IdRta, sizeof(IdRta) ) == COPYFAIL ) {
  178. rio_dprintk (RIO_DEBUG_CMD, "RIO_IDENTIFY_RTA copy failedn");
  179. p->RIOError.Error = COPYIN_FAILED;
  180. return EFAULT;
  181. }
  182. for ( Host = 0 ; Host < p->RIONumHosts; Host++ ) {
  183. uint Rta;
  184. struct Host *HostP = &p->RIOHosts[Host];
  185. for ( Rta = 0; Rta < RTAS_PER_HOST; Rta++ ) {
  186. struct Map *MapP = &HostP->Mapping[Rta];
  187. if ( MapP->RtaUniqueNum == IdRta.RtaUnique ) {
  188. uint Link;
  189. /*
  190. ** now, lets just check we have a route to it...
  191. ** IF the routing stuff is working, then one of the
  192. ** topology entries for this unit will have a legit
  193. ** route *somewhere*. We care not where - if its got
  194. ** any connections, we can get to it.
  195. */
  196. for ( Link = 0; Link < LINKS_PER_UNIT; Link++ ) {
  197. if ( MapP->Topology[Link].Unit <= (uchar)MAX_RUP ) {
  198. /*
  199. ** Its worth trying the operation...
  200. */
  201. struct CmdBlk *CmdBlkP;
  202. rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTAn");
  203. CmdBlkP = RIOGetCmdBlk();
  204. if ( !CmdBlkP ) {
  205. rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: GetCmdBlk failedn");
  206. return ENXIO;
  207. }
  208. CmdBlkP->Packet.dest_unit = MapP->ID;
  209. CmdBlkP->Packet.dest_port = BOOT_RUP;
  210. CmdBlkP->Packet.src_unit  = 0;
  211. CmdBlkP->Packet.src_port  = BOOT_RUP;
  212. CmdBlkP->Packet.len    = 0x84;
  213. CmdBlkP->Packet.data[0]   = IDENTIFY;
  214. CmdBlkP->Packet.data[1]   = 0;
  215. CmdBlkP->Packet.data[2]   = IdRta.ID;
  216. if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
  217. rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: Failed to queue commandn");
  218. return EIO;
  219. }
  220. return 0;
  221. }
  222. }
  223. }
  224. }
  225. return ENOENT;
  226. }
  227. int
  228. RIOKillNeighbour(p, arg)
  229. struct rio_info * p;
  230. caddr_t arg;
  231. {
  232. uint Host;
  233. uint ID;
  234. struct Host *HostP;
  235. struct CmdBlk *CmdBlkP;
  236. rio_dprintk (RIO_DEBUG_CMD, "KILL HOST NEIGHBOURn");
  237. if ( copyin( (int)arg, (caddr_t)&KillUnit, sizeof(KillUnit) ) == COPYFAIL ) {
  238. rio_dprintk (RIO_DEBUG_CMD, "RIO_KILL_NEIGHBOUR copy failedn");
  239. p->RIOError.Error = COPYIN_FAILED;
  240. return EFAULT;
  241. }
  242. if ( KillUnit.Link > 3 )
  243. return ENXIO;
  244.  
  245. CmdBlkP = RIOGetCmdBlk();
  246. if ( !CmdBlkP ) {
  247. rio_dprintk (RIO_DEBUG_CMD, "UFOAD: GetCmdBlk failedn");
  248. return ENXIO;
  249. }
  250. CmdBlkP->Packet.dest_unit = 0;
  251. CmdBlkP->Packet.src_unit  = 0;
  252. CmdBlkP->Packet.dest_port = BOOT_RUP;
  253. CmdBlkP->Packet.src_port  = BOOT_RUP;
  254. CmdBlkP->Packet.len    = 0x84;
  255. CmdBlkP->Packet.data[0]   = UFOAD;
  256. CmdBlkP->Packet.data[1]   = KillUnit.Link;
  257. CmdBlkP->Packet.data[2]   = UFOAD_MAGIC & 0xFF;
  258. CmdBlkP->Packet.data[3]   = (UFOAD_MAGIC >> 8) & 0xFF;
  259. for ( Host = 0; Host < p->RIONumHosts; Host++ ) {
  260. ID = 0;
  261. HostP = &p->RIOHosts[Host];
  262. if ( HostP->UniqueNum == KillUnit.UniqueNum ) {
  263. if ( RIOQueueCmdBlk( HostP, RTAS_PER_HOST+KillUnit.Link,
  264. CmdBlkP) == RIO_FAIL ) {
  265. rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue commandn");
  266. return EIO;
  267. }
  268. return 0;
  269. }
  270. for ( ID=0; ID < RTAS_PER_HOST; ID++ ) {
  271. if ( HostP->Mapping[ID].RtaUniqueNum == KillUnit.UniqueNum ) {
  272. CmdBlkP->Packet.dest_unit = ID+1;
  273. if ( RIOQueueCmdBlk( HostP, ID, CmdBlkP) == RIO_FAIL ) {
  274. rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue commandn");
  275. return EIO;
  276. }
  277. return 0;
  278. }
  279. }
  280. }
  281. RIOFreeCmdBlk( CmdBlkP );
  282. return ENXIO;
  283. }
  284. int
  285. RIOSuspendBootRta(HostP, ID, Link)
  286. struct Host *HostP;
  287. int ID;
  288. int Link; 
  289. {
  290. struct CmdBlk *CmdBlkP;
  291. rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA ID %d, link %cn", ID, 'A' + Link);
  292. CmdBlkP = RIOGetCmdBlk();
  293. if ( !CmdBlkP ) {
  294. rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: GetCmdBlk failedn");
  295. return ENXIO;
  296. }
  297. CmdBlkP->Packet.dest_unit = ID;
  298. CmdBlkP->Packet.dest_port = BOOT_RUP;
  299. CmdBlkP->Packet.src_unit  = 0;
  300. CmdBlkP->Packet.src_port  = BOOT_RUP;
  301. CmdBlkP->Packet.len    = 0x84;
  302. CmdBlkP->Packet.data[0]   = IWAIT;
  303. CmdBlkP->Packet.data[1]   = Link;
  304. CmdBlkP->Packet.data[2]   = IWAIT_MAGIC & 0xFF;
  305. CmdBlkP->Packet.data[3]   = (IWAIT_MAGIC >> 8) & 0xFF;
  306. if ( RIOQueueCmdBlk( HostP, ID - 1, CmdBlkP) == RIO_FAIL ) {
  307. rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: Failed to queue iwait commandn");
  308. return EIO;
  309. }
  310. return 0;
  311. }
  312. int
  313. RIOFoadWakeup(p)
  314. struct rio_info * p;
  315. {
  316. int port;
  317. register struct Port *PortP;
  318. unsigned long flags;
  319. for ( port=0; port<RIO_PORTS; port++) {
  320. PortP = p->RIOPortp[port];
  321. rio_spin_lock_irqsave(&PortP->portSem, flags);
  322. PortP->Config = 0;
  323. PortP->State = 0;
  324. PortP->InUse = NOT_INUSE;
  325. PortP->PortState = 0;
  326. PortP->FlushCmdBodge = 0;
  327. PortP->ModemLines = 0;
  328. PortP->ModemState = 0;
  329. PortP->CookMode = 0;
  330. PortP->ParamSem = 0;
  331. PortP->Mapped = 0;
  332. PortP->WflushFlag = 0;
  333. PortP->MagicFlags = 0;
  334. PortP->RxDataStart = 0;
  335. PortP->TxBufferIn = 0;
  336. PortP->TxBufferOut = 0;
  337. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  338. }
  339. return(0);
  340. }
  341. /*
  342. ** Incoming command on the COMMAND_RUP to be processed.
  343. */
  344. int
  345. RIOCommandRup(p, Rup, HostP, PacketP)
  346. struct rio_info * p;
  347. uint Rup;
  348. struct Host *HostP;
  349. PKT *PacketP; 
  350. {
  351. struct PktCmd *PktCmdP = (struct PktCmd *)PacketP->data;
  352. struct Port *PortP;
  353. struct UnixRup *UnixRupP;
  354. ushort SysPort;
  355. ushort ReportedModemStatus;
  356. ushort rup;
  357. ushort subCommand;
  358. unsigned long flags;
  359. func_enter ();
  360. #ifdef CHECK
  361. CheckHost( Host );
  362. CheckHostP( HostP );
  363. CheckPacketP( PacketP );
  364. #endif
  365. /*
  366. ** 16 port RTA note:
  367. ** Command rup packets coming from the RTA will have pkt->data[1] (which
  368. ** translates to PktCmdP->PhbNum) set to the host port number for the
  369. ** particular unit. To access the correct BaseSysPort for a 16 port RTA,
  370. ** we can use PhbNum to get the rup number for the appropriate 8 port
  371. ** block (for the first block, this should be equal to 'Rup').
  372. */
  373. rup = RBYTE(PktCmdP->PhbNum) / (ushort)PORTS_PER_RTA;
  374. UnixRupP = &HostP->UnixRups[rup];
  375. SysPort = UnixRupP->BaseSysPort + 
  376. (RBYTE(PktCmdP->PhbNum) % (ushort)PORTS_PER_RTA);
  377. rio_dprintk (RIO_DEBUG_CMD, "Command on rup %d, port %dn", rup, SysPort);
  378. #ifdef CHECK
  379. CheckRup( rup );
  380. CheckUnixRupP( UnixRupP );
  381. #endif
  382. if ( UnixRupP->BaseSysPort == NO_PORT ) {
  383. rio_dprintk (RIO_DEBUG_CMD, "OBSCURE ERROR!n");
  384. rio_dprintk (RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Supportn");
  385. rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Host number %d, name ``%s''n", 
  386.      HostP-p->RIOHosts, HostP->Name );
  387. rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Rup number  0x%xn", rup);
  388. if ( Rup >= (ushort)MAX_RUP ) {
  389. rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''n",
  390.      HostP->Mapping[Rup].Name);
  391. } else
  392. rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''n", 
  393.      ('A' + Rup - MAX_RUP), HostP->Name);
  394. rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%xn",
  395.      PacketP->dest_unit, PacketP->dest_port );
  396. rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Source   0x%x:0x%xn",
  397.      PacketP->src_unit, PacketP->src_port );
  398. rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Length   0x%x (%d)n", PacketP->len,PacketP->len );
  399. rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Control  0x%x (%d)n", PacketP->control, PacketP->control);
  400. rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Check    0x%x (%d)n", PacketP->csum, PacketP->csum );
  401. rio_dprintk (RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, 
  402. Command Code 0x%xn", PktCmdP->PhbNum, PktCmdP->Command );
  403. return TRUE;
  404. }
  405. #ifdef CHECK
  406. CheckSysPort( SysPort );
  407. #endif
  408. PortP = p->RIOPortp[ SysPort ];
  409. rio_spin_lock_irqsave(&PortP->portSem, flags);
  410. switch( RBYTE(PktCmdP->Command) ) {
  411. case BREAK_RECEIVED:
  412. rio_dprintk (RIO_DEBUG_CMD, "Received a break!n");
  413. /* If the current line disc. is not multi-threading and
  414.     the current processor is not the default, reset rup_intr
  415.     and return FALSE to ensure that the command packet is
  416.     not freed. */
  417. /* Call tmgr HANGUP HERE */
  418. /* Fix this later when every thing works !!!! RAMRAJ */
  419. gs_got_break (&PortP->gs);
  420. break;
  421. case COMPLETE:
  422. rio_dprintk (RIO_DEBUG_CMD, "Command complete on phb %d host %dn",
  423.      RBYTE(PktCmdP->PhbNum), HostP-p->RIOHosts);
  424. subCommand = 1;
  425. switch (RBYTE(PktCmdP->SubCommand)) {
  426. case MEMDUMP :
  427. rio_dprintk (RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%xn",
  428.      RBYTE(PktCmdP->SubCommand), RWORD(PktCmdP->SubAddr));
  429. break;
  430. case READ_REGISTER :
  431. rio_dprintk (RIO_DEBUG_CMD, "Read register (0x%x)n", RWORD(PktCmdP->SubAddr));
  432. p->CdRegister = (RBYTE(PktCmdP->ModemStatus) & MSVR1_HOST);
  433. break;
  434. default :
  435. subCommand = 0;
  436. break;
  437. }
  438. if (subCommand)
  439. break;
  440. rio_dprintk (RIO_DEBUG_CMD, "New status is 0x%x was 0x%xn",
  441.      RBYTE(PktCmdP->PortStatus),PortP->PortState);
  442. if (PortP->PortState != RBYTE(PktCmdP->PortStatus)) {
  443. rio_dprintk (RIO_DEBUG_CMD, "Mark status & wakeupn");
  444. PortP->PortState = RBYTE(PktCmdP->PortStatus);
  445. /* What should we do here ...
  446. wakeup( &PortP->PortState );
  447. */
  448. } else 
  449. rio_dprintk (RIO_DEBUG_CMD, "No changen");
  450. /* FALLTHROUGH */
  451. case MODEM_STATUS:
  452. /*
  453. ** Knock out the tbusy and tstop bits, as these are not relevant
  454. ** to the check for modem status change (they're just there because
  455. ** it's a convenient place to put them!).
  456. */
  457. ReportedModemStatus = RBYTE(PktCmdP->ModemStatus);
  458. if ((PortP->ModemState & MSVR1_HOST) ==
  459. (ReportedModemStatus & MSVR1_HOST)) {
  460. rio_dprintk (RIO_DEBUG_CMD, "Modem status unchanged 0x%xn", PortP->ModemState);
  461. /*
  462. ** Update ModemState just in case tbusy or tstop states have
  463. ** changed.
  464. */
  465. PortP->ModemState = ReportedModemStatus;
  466. }
  467. else {
  468. rio_dprintk (RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%xn",
  469.      PortP->ModemState, ReportedModemStatus);
  470. PortP->ModemState = ReportedModemStatus;
  471. #ifdef MODEM_SUPPORT
  472. if ( PortP->Mapped ) {
  473. /***********************************************************
  474. *************************************************************
  475. ***    ***
  476. ***   M O D E M   S T A T E   C H A N G E   ***
  477. ***    ***
  478. *************************************************************
  479. ***********************************************************/
  480. /*
  481. ** If the device is a modem, then check the modem
  482. ** carrier.
  483. */
  484. if (PortP->gs.tty == NULL)
  485. break;
  486. if (PortP->gs.tty->termios == NULL)
  487. break;
  488.   
  489. if (!(PortP->gs.tty->termios->c_cflag & CLOCAL) &&
  490. ((PortP->State & (RIO_MOPEN|RIO_WOPEN)))) {
  491. rio_dprintk (RIO_DEBUG_CMD, "Is there a Carrier?n");
  492. /*
  493. ** Is there a carrier?
  494. */
  495. if ( PortP->ModemState & MSVR1_CD ) {
  496. /*
  497. ** Has carrier just appeared?
  498. */
  499. if (!(PortP->State & RIO_CARR_ON)) {
  500. rio_dprintk (RIO_DEBUG_CMD, "Carrier just came up.n");
  501. PortP->State |= RIO_CARR_ON;
  502. /*
  503. ** wakeup anyone in WOPEN
  504. */
  505. if (PortP->State & (PORT_ISOPEN | RIO_WOPEN) )
  506. wake_up_interruptible (&PortP->gs.open_wait);
  507. #ifdef STATS
  508. PortP->Stat.ModemOnCnt++;
  509. #endif
  510. }
  511. } else {
  512. /*
  513. ** Has carrier just dropped?
  514. */
  515. if (PortP->State & RIO_CARR_ON) {
  516. if (PortP->State & (PORT_ISOPEN|RIO_WOPEN|RIO_MOPEN))
  517. tty_hangup (PortP->gs.tty);
  518. PortP->State &= ~RIO_CARR_ON;
  519. rio_dprintk (RIO_DEBUG_CMD, "Carrirer just went downn");
  520. #ifdef STATS
  521. PortP->Stat.ModemOffCnt++;
  522. #endif
  523. }
  524. }
  525. }
  526. }
  527. #endif
  528. }
  529. break;
  530. default:
  531. rio_dprintk (RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %dn",
  532.      RBYTE(PktCmdP->Command),HostP-p->RIOHosts);
  533. break;
  534. }
  535. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  536. func_exit ();
  537. return TRUE;
  538. }
  539. /*
  540. ** The command mechanism:
  541. ** Each rup has a chain of commands associated with it.
  542. ** This chain is maintained by routines in this file.
  543. ** Periodically we are called and we run a quick check of all the
  544. ** active chains to determine if there is a command to be executed,
  545. ** and if the rup is ready to accept it.
  546. **
  547. */
  548. /*
  549. ** Allocate an empty command block.
  550. */
  551. struct CmdBlk *
  552. RIOGetCmdBlk()
  553. {
  554. struct CmdBlk *CmdBlkP;
  555. CmdBlkP = (struct CmdBlk *)sysbrk(sizeof(struct CmdBlk));
  556. if (CmdBlkP)
  557. bzero(CmdBlkP, sizeof(struct CmdBlk));
  558. return CmdBlkP;
  559. }
  560. /*
  561. ** Return a block to the head of the free list.
  562. */
  563. void
  564. RIOFreeCmdBlk(CmdBlkP)
  565. struct CmdBlk *CmdBlkP;
  566. {
  567. sysfree((void *)CmdBlkP, sizeof(struct CmdBlk));
  568. }
  569. /*
  570. ** attach a command block to the list of commands to be performed for
  571. ** a given rup.
  572. */
  573. int
  574. RIOQueueCmdBlk(HostP, Rup, CmdBlkP)
  575. struct Host *HostP;
  576. uint Rup;
  577. struct CmdBlk *CmdBlkP;
  578. {
  579. struct CmdBlk **Base;
  580. struct UnixRup *UnixRupP;
  581. unsigned long flags;
  582. #ifdef CHECK
  583. CheckHostP( HostP );
  584. CheckRup( Rup );
  585. CheckCmdBlkP( CmdBlkP );
  586. #endif
  587. if ( Rup >= (ushort)(MAX_RUP+LINKS_PER_UNIT) ) {
  588. rio_dprintk (RIO_DEBUG_CMD, "Illegal rup number %d in RIOQueueCmdBlkn",Rup);
  589. RIOFreeCmdBlk( CmdBlkP );
  590. return RIO_FAIL;
  591. }
  592. UnixRupP = &HostP->UnixRups[Rup];
  593. rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
  594. /*
  595. ** If the RUP is currently inactive, then put the request
  596. ** straight on the RUP....
  597. */
  598. if ( (UnixRupP->CmdsWaitingP == NULL) && (UnixRupP->CmdPendingP == NULL) && 
  599.      (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE ) &&
  600. (CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP)(CmdBlkP->PreArg,CmdBlkP)
  601. :TRUE)) {
  602. rio_dprintk (RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%xn",
  603.      CmdBlkP->Packet.data[0]);
  604.                                             
  605. /*
  606. ** Whammy! blat that pack!
  607. */
  608. HostP->Copy( (caddr_t)&CmdBlkP->Packet, 
  609. RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt ), sizeof(PKT) );
  610. /*
  611. ** place command packet on the pending position.
  612. */
  613. UnixRupP->CmdPendingP = CmdBlkP;
  614. /*
  615. ** set the command register
  616. */
  617. WWORD(UnixRupP->RupP->txcontrol , TX_PACKET_READY);
  618. rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
  619. return RIO_SUCCESS;
  620. }
  621. rio_dprintk (RIO_DEBUG_CMD, "RUP active - en-queingn");
  622. if ( UnixRupP->CmdsWaitingP != NULL)
  623. rio_dprintk (RIO_DEBUG_CMD, "Rup active - command waitingn");
  624. if ( UnixRupP->CmdPendingP != NULL )
  625. rio_dprintk (RIO_DEBUG_CMD, "Rup active - command pendingn");
  626. if ( RWORD(UnixRupP->RupP->txcontrol) != TX_RUP_INACTIVE )
  627. rio_dprintk (RIO_DEBUG_CMD, "Rup active - command rup not readyn");
  628. Base = &UnixRupP->CmdsWaitingP;
  629. rio_dprintk (RIO_DEBUG_CMD, "First try to queue cmdblk 0x%x at 0x%xn", (int)CmdBlkP,(int)Base);
  630. while ( *Base ) {
  631. rio_dprintk (RIO_DEBUG_CMD, "Command cmdblk 0x%x heren", (int)(*Base));
  632. Base = &((*Base)->NextP);
  633. rio_dprintk (RIO_DEBUG_CMD, "Now try to queue cmd cmdblk 0x%x at 0x%xn",
  634.      (int)CmdBlkP,(int)Base);
  635. }
  636. rio_dprintk (RIO_DEBUG_CMD, "Will queue cmdblk 0x%x at 0x%xn",(int)CmdBlkP,(int)Base);
  637. *Base = CmdBlkP;
  638. CmdBlkP->NextP = NULL;
  639. rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
  640. return RIO_SUCCESS;
  641. }
  642. /*
  643. ** Here we go - if there is an empty rup, fill it!
  644. ** must be called at splrio() or higher.
  645. */
  646. void
  647. RIOPollHostCommands(p, HostP)
  648. struct rio_info * p;
  649. struct Host * HostP;
  650. {
  651. register struct CmdBlk *CmdBlkP;
  652. register struct UnixRup *UnixRupP;
  653. struct PKT *PacketP;
  654. ushort Rup;
  655. unsigned long flags;
  656. Rup = MAX_RUP+LINKS_PER_UNIT;
  657. do { /* do this loop for each RUP */
  658. /*
  659. ** locate the rup we are processing & lock it
  660. */
  661. UnixRupP = &HostP->UnixRups[--Rup];
  662. spin_lock_irqsave(&UnixRupP->RupLock, flags);
  663. /*
  664. ** First check for incoming commands:
  665. */
  666. if ( RWORD(UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE ) {
  667. int FreeMe;
  668. PacketP =(PKT *)RIO_PTR(HostP->Caddr,RWORD(UnixRupP->RupP->rxpkt));
  669. ShowPacket( DBG_CMD, PacketP );
  670. switch ( RBYTE(PacketP->dest_port) ) {
  671. case BOOT_RUP:
  672. rio_dprintk (RIO_DEBUG_CMD, "Incoming Boot %s packet '%x'n", 
  673. RBYTE(PacketP->len) & 0x80 ? "Command":"Data", 
  674.      RBYTE(PacketP->data[0])); 
  675. rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
  676. FreeMe= RIOBootRup(p, Rup,HostP,PacketP);
  677. rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
  678. break;
  679. case COMMAND_RUP:
  680. /*
  681. ** Free the RUP lock as loss of carrier causes a
  682. ** ttyflush which will (eventually) call another
  683. ** routine that uses the RUP lock.
  684. */
  685. rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
  686. FreeMe= RIOCommandRup(p, Rup,HostP,PacketP);
  687. if (PacketP->data[5] == MEMDUMP) {
  688. rio_dprintk (RIO_DEBUG_CMD, "Memdump from 0x%x completen",
  689.      *(ushort *) &(PacketP->data[6]));
  690. HostP->Copy( (caddr_t)&(PacketP->data[8]), 
  691. (caddr_t)p->RIOMemDump, 32 );
  692. }
  693. rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
  694. break;
  695. case ROUTE_RUP:
  696. rio_spin_unlock_irqrestore( &UnixRupP->RupLock, flags);
  697. FreeMe = RIORouteRup(p, Rup, HostP, PacketP );
  698. rio_spin_lock_irqsave( &UnixRupP->RupLock, flags );
  699. break;
  700. default:
  701. rio_dprintk (RIO_DEBUG_CMD, "Unknown RUP %dn", RBYTE(PacketP->dest_port));
  702. FreeMe = 1;
  703. break;
  704. }
  705. if ( FreeMe ) {
  706. rio_dprintk (RIO_DEBUG_CMD, "Free processed incoming command packetn");
  707. put_free_end(HostP,PacketP);
  708. WWORD(UnixRupP->RupP->rxcontrol , RX_RUP_INACTIVE);
  709. if ( RWORD(UnixRupP->RupP->handshake)==PHB_HANDSHAKE_SET ) {
  710. rio_dprintk (RIO_DEBUG_CMD, "Handshake rup %dn",Rup);
  711. WWORD(UnixRupP->RupP->handshake,
  712. PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
  713. }
  714. }
  715. }
  716. /*
  717. ** IF a command was running on the port, 
  718. ** and it has completed, then tidy it up.
  719. */
  720. if ( (CmdBlkP = UnixRupP->CmdPendingP) && /* ASSIGN! */
  721.      (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
  722. /*
  723. ** we are idle.
  724. ** there is a command in pending.
  725. ** Therefore, this command has finished.
  726. ** So, wakeup whoever is waiting for it (and tell them
  727. ** what happened).
  728. */
  729. if ( CmdBlkP->Packet.dest_port == BOOT_RUP )
  730. rio_dprintk (RIO_DEBUG_CMD, "Free Boot %s Command Block '%x'n", 
  731. CmdBlkP->Packet.len & 0x80 ? "Command":"Data", 
  732.      CmdBlkP->Packet.data[0]);
  733. rio_dprintk (RIO_DEBUG_CMD, "Command 0x%x completedn",(int)CmdBlkP);
  734. /*
  735. ** Clear the Rup lock to prevent mutual exclusion.
  736. */
  737. if ( CmdBlkP->PostFuncP ) {
  738. rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
  739. (*CmdBlkP->PostFuncP) (CmdBlkP->PostArg,CmdBlkP);
  740. rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
  741. }
  742. /*
  743. ** ....clear the pending flag....
  744. */
  745. UnixRupP->CmdPendingP = NULL;
  746. /*
  747. ** ....and return the command block to the freelist.
  748. */
  749. RIOFreeCmdBlk( CmdBlkP );
  750. }
  751. /*
  752. ** If there is a command for this rup, and the rup
  753. ** is idle, then process the command
  754. */
  755. if ( (CmdBlkP = UnixRupP->CmdsWaitingP) && /* ASSIGN! */
  756. (UnixRupP->CmdPendingP == NULL) &&
  757.      (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
  758. /*
  759. ** if the pre-function is non-zero, call it.
  760. ** If it returns RIO_FAIL then don't
  761. ** send this command yet!
  762. */
  763. #ifdef CHECK
  764. CheckCmdBlkP (CmdBlkP);
  765. #endif
  766. if ( !(CmdBlkP->PreFuncP ?
  767. (*CmdBlkP->PreFuncP)(CmdBlkP->PreArg, CmdBlkP) : TRUE)) {
  768. rio_dprintk (RIO_DEBUG_CMD, "Not ready to start command 0x%xn",(int)CmdBlkP);
  769. }
  770. else {
  771. rio_dprintk (RIO_DEBUG_CMD, "Start new command 0x%x Cmd byte is 0x%xn",
  772.      (int)CmdBlkP, CmdBlkP->Packet.data[0]);
  773. /*
  774. ** Whammy! blat that pack!
  775. */
  776. #ifdef CHECK
  777. CheckPacketP ((PKT *)RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt));
  778. #endif
  779. HostP->Copy( (caddr_t)&CmdBlkP->Packet, 
  780. RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt), sizeof(PKT));
  781. /*
  782. ** remove the command from the rup command queue...
  783. */
  784. UnixRupP->CmdsWaitingP = CmdBlkP->NextP;
  785. /*
  786. ** ...and place it on the pending position.
  787. */
  788. UnixRupP->CmdPendingP = CmdBlkP;
  789. /*
  790. ** set the command register
  791. */
  792. WWORD(UnixRupP->RupP->txcontrol,TX_PACKET_READY);
  793. /*
  794. ** the command block will be freed
  795. ** when the command has been processed.
  796. */
  797. }
  798. }
  799. spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
  800. } while ( Rup );
  801. }
  802. /*
  803. ** Return the length of the named string
  804. */
  805. int
  806. RIOStrlen(Str)
  807. register char *Str;
  808. {
  809. register int len = 0;
  810. while ( *Str++ )
  811. len++;
  812. return len;
  813. }
  814. /*
  815. ** compares s1 to s2 and return 0 if they match.
  816. */
  817. int
  818. RIOStrCmp(s1, s2)
  819. register char *s1;
  820. register char *s2;
  821. {
  822. while ( *s1 && *s2 && *s1==*s2 )
  823. s1++, s2++;
  824. return *s1-*s2;
  825. }
  826. /*
  827. ** compares s1 to s2 for upto n bytes and return 0 if they match.
  828. */
  829. int
  830. RIOStrnCmp(s1, s2, n)
  831. register char *s1;
  832. register char *s2;
  833. int n;
  834. {
  835. while ( n && *s1 && *s2 && *s1==*s2 )
  836. n--, s1++, s2++;
  837. return n ? *s1!=*s2 : 0;
  838. }
  839. /*
  840. ** copy up to 'len' bytes from 'from' to 'to'.
  841. */
  842. void
  843. RIOStrNCpy(to, from, len)
  844. char *to;
  845. char *from;
  846. int len; 
  847. {
  848. while ( len-- && (*to++ = *from++) )
  849. ;
  850. to[-1]='';
  851. }
  852. int
  853. RIOWFlushMark(iPortP, CmdBlkP)
  854. int iPortP;
  855. struct CmdBlk *CmdBlkP;
  856. {
  857. struct Port * PortP = (struct Port *)iPortP;
  858. unsigned long flags;
  859. rio_spin_lock_irqsave(&PortP->portSem, flags);
  860. #ifdef CHECK
  861. CheckPortP( PortP );
  862. #endif
  863. PortP->WflushFlag++;
  864. PortP->MagicFlags |= MAGIC_FLUSH;
  865. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  866. return RIOUnUse( iPortP, CmdBlkP );
  867. }
  868. int
  869. RIORFlushEnable(iPortP, CmdBlkP)
  870. int iPortP;
  871. struct CmdBlk *CmdBlkP; 
  872. {
  873. struct Port * PortP = (struct Port *)iPortP;
  874. PKT *PacketP;
  875. unsigned long flags;
  876. rio_spin_lock_irqsave(&PortP->portSem, flags);
  877. while ( can_remove_receive(&PacketP, PortP) ) {
  878. remove_receive(PortP);
  879. ShowPacket(DBG_PROC, PacketP );
  880. put_free_end( PortP->HostP, PacketP );
  881. }
  882. if ( RWORD(PortP->PhbP->handshake)==PHB_HANDSHAKE_SET ) {
  883. /*
  884. ** MAGIC! (Basically, handshake the RX buffer, so that
  885. ** the RTAs upstream can be re-enabled.)
  886. */
  887. rio_dprintk (RIO_DEBUG_CMD, "Util: Set RX handshake bitn");
  888. WWORD(PortP->PhbP->handshake, PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
  889. }
  890. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  891. return RIOUnUse( iPortP, CmdBlkP );
  892. }
  893. int
  894. RIOUnUse(iPortP, CmdBlkP)
  895. int iPortP;
  896. struct CmdBlk *CmdBlkP; 
  897. {
  898. struct Port * PortP = (struct Port *)iPortP;
  899. unsigned long flags;
  900. rio_spin_lock_irqsave(&PortP->portSem, flags);
  901. #ifdef CHECK
  902. CheckPortP( PortP );
  903. #endif
  904. rio_dprintk (RIO_DEBUG_CMD, "Decrement in use count for portn");
  905. if (PortP->InUse) {
  906. if ( --PortP->InUse != NOT_INUSE ) {
  907. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  908. return 0;
  909. }
  910. }
  911. /*
  912. ** While PortP->InUse is set (i.e. a preemptive command has been sent to
  913. ** the RTA and is awaiting completion), any transmit data is prevented from
  914. ** being transferred from the write queue into the transmit packets
  915. ** (add_transmit) and no furthur transmit interrupt will be sent for that
  916. ** data. The next interrupt will occur up to 500ms later (RIOIntr is called
  917. ** twice a second as a saftey measure). This was the case when kermit was
  918. ** used to send data into a RIO port. After each packet was sent, TCFLSH
  919. ** was called to flush the read queue preemptively. PortP->InUse was
  920. ** incremented, thereby blocking the 6 byte acknowledgement packet
  921. ** transmitted back. This acknowledgment hung around for 500ms before
  922. ** being sent, thus reducing input performance substantially!.
  923. ** When PortP->InUse becomes NOT_INUSE, we must ensure that any data
  924. ** hanging around in the transmit buffer is sent immediately.
  925. */
  926. WWORD(PortP->HostP->ParmMapP->tx_intr, 1);
  927. /* What to do here ..
  928. wakeup( (caddr_t)&(PortP->InUse) );
  929. */
  930. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  931. return 0;
  932. }
  933. void
  934. ShowPacket(Flags, PacketP)
  935. uint Flags;
  936. struct PKT *PacketP; 
  937. {
  938. }
  939. /*
  940. ** 
  941. ** How to use this file:
  942. ** 
  943. ** To send a command down a rup, you need to allocate a command block, fill
  944. ** in the packet information, fill in the command number, fill in the pre-
  945. ** and post- functions and arguments, and then add the command block to the
  946. ** queue of command blocks for the port in question. When the port is idle,
  947. ** then the pre-function will be called. If this returns RIO_FAIL then the
  948. ** command will be re-queued and tried again at a later date (probably in one
  949. ** clock tick). If the pre-function returns NOT RIO_FAIL, then the command
  950. ** packet will be queued on the RUP, and the txcontrol field set to the
  951. ** command number. When the txcontrol field has changed from being the
  952. ** command number, then the post-function will be called, with the argument
  953. ** specified earlier, a pointer to the command block, and the value of
  954. ** txcontrol.
  955. ** 
  956. ** To allocate a command block, call RIOGetCmdBlk(). This returns a pointer
  957. ** to the command block structure allocated, or NULL if there aren't any.
  958. ** The block will have been zeroed for you.
  959. ** 
  960. ** The structure has the following fields:
  961. ** 
  962. ** struct CmdBlk
  963. ** {
  964. **  struct CmdBlk *NextP;   ** Pointer to next command block   **
  965. **  struct PKT  Packet; ** A packet, to copy to the rup **
  966. ** int  (*PreFuncP)();  ** The func to call to check if OK **
  967. ** int  PreArg; ** The arg for the func **
  968. ** int  (*PostFuncP)(); ** The func to call when completed **
  969. ** int  PostArg;    ** The arg for the func **
  970. ** };
  971. ** 
  972. ** You need to fill in ALL fields EXCEPT NextP, which is used to link the
  973. ** blocks together either on the free list or on the Rup list.
  974. ** 
  975. ** Packet is an actual packet structure to be filled in with the packet
  976. ** information associated with the command. You need to fill in everything,
  977. ** as the command processore doesn't process the command packet in any way.
  978. ** 
  979. ** The PreFuncP is called before the packet is enqueued on the host rup.
  980. ** PreFuncP is called as (*PreFuncP)(PreArg, CmdBlkP);. PreFuncP must
  981. ** return !RIO_FAIL to have the packet queued on the rup, and RIO_FAIL
  982. ** if the packet is NOT to be queued.
  983. ** 
  984. ** The PostFuncP is called when the command has completed. It is called
  985. ** as (*PostFuncP)(PostArg, CmdBlkP, txcontrol);. PostFuncP is not expected
  986. ** to return a value. PostFuncP does NOT need to free the command block,
  987. ** as this happens automatically after PostFuncP returns.
  988. ** 
  989. ** Once the command block has been filled in, it is attached to the correct
  990. ** queue by calling RIOQueueCmdBlk( HostP, Rup, CmdBlkP ) where HostP is
  991. ** a pointer to the struct Host, Rup is the NUMBER of the rup (NOT a pointer
  992. ** to it!), and CmdBlkP is the pointer to the command block allocated using
  993. ** RIOGetCmdBlk().
  994. ** 
  995. */