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