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 : rioroute.c 24** SID : 1.3 25** Last Modified : 11/6/98 10:33:46 26** Retrieved : 11/6/98 10:33:50 27** 28** ident @(#)rioroute.c 1.3 29** 30** ----------------------------------------------------------------------------- 31*/ 32 33#include <linux/module.h> 34#include <linux/errno.h> 35#include <asm/io.h> 36#include <asm/system.h> 37#include <asm/string.h> 38#include <asm/uaccess.h> 39 40#include <linux/termios.h> 41#include <linux/serial.h> 42 43#include <linux/generic_serial.h> 44 45 46#include "linux_compat.h" 47#include "rio_linux.h" 48#include "pkt.h" 49#include "daemon.h" 50#include "rio.h" 51#include "riospace.h" 52#include "cmdpkt.h" 53#include "map.h" 54#include "rup.h" 55#include "port.h" 56#include "riodrvr.h" 57#include "rioinfo.h" 58#include "func.h" 59#include "errors.h" 60#include "pci.h" 61 62#include "parmmap.h" 63#include "unixrup.h" 64#include "board.h" 65#include "host.h" 66#include "phb.h" 67#include "link.h" 68#include "cmdblk.h" 69#include "route.h" 70#include "cirrus.h" 71#include "rioioctl.h" 72#include "param.h" 73 74static int RIOCheckIsolated(struct rio_info *, struct Host *, unsigned int); 75static int RIOIsolate(struct rio_info *, struct Host *, unsigned int); 76static int RIOCheck(struct Host *, unsigned int); 77static void RIOConCon(struct rio_info *, struct Host *, unsigned int, unsigned int, unsigned int, unsigned int, int); 78 79 80/* 81** Incoming on the ROUTE_RUP 82** I wrote this while I was tired. Forgive me. 83*/ 84int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT __iomem * PacketP) 85{ 86 struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *) PacketP->data; 87 struct PktCmd_M *PktReplyP; 88 struct CmdBlk *CmdBlkP; 89 struct Port *PortP; 90 struct Map *MapP; 91 struct Top *TopP; 92 int ThisLink, ThisLinkMin, ThisLinkMax; 93 int port; 94 int Mod, Mod1, Mod2; 95 unsigned short RtaType; 96 unsigned int RtaUniq; 97 unsigned int ThisUnit, ThisUnit2; /* 2 ids to accommodate 16 port RTA */ 98 unsigned int OldUnit, NewUnit, OldLink, NewLink; 99 char *MyType, *MyName; 100 int Lies; 101 unsigned long flags; 102 103 /* 104 ** Is this unit telling us it's current link topology? 105 */ 106 if (readb(&PktCmdP->Command) == ROUTE_TOPOLOGY) { 107 MapP = HostP->Mapping; 108 109 /* 110 ** The packet can be sent either by the host or by an RTA. 111 ** If it comes from the host, then we need to fill in the 112 ** Topology array in the host structure. If it came in 113 ** from an RTA then we need to fill in the Mapping structure's 114 ** Topology array for the unit. 115 */ 116 if (Rup >= (unsigned short) MAX_RUP) { 117 ThisUnit = HOST_ID; 118 TopP = HostP->Topology; 119 MyType = "Host"; 120 MyName = HostP->Name; 121 ThisLinkMin = ThisLinkMax = Rup - MAX_RUP; 122 } else { 123 ThisUnit = Rup + 1; 124 TopP = HostP->Mapping[Rup].Topology; 125 MyType = "RTA"; 126 MyName = HostP->Mapping[Rup].Name; 127 ThisLinkMin = 0; 128 ThisLinkMax = LINKS_PER_UNIT - 1; 129 } 130 131 /* 132 ** Lies will not be tolerated. 133 ** If any pair of links claim to be connected to the same 134 ** place, then ignore this packet completely. 135 */ 136 Lies = 0; 137 for (ThisLink = ThisLinkMin + 1; ThisLink <= ThisLinkMax; ThisLink++) { 138 /* 139 ** it won't lie about network interconnect, total disconnects 140 ** and no-IDs. (or at least, it doesn't *matter* if it does) 141 */ 142 if (readb(&PktCmdP->RouteTopology[ThisLink].Unit) > (unsigned short) MAX_RUP) 143 continue; 144 145 for (NewLink = ThisLinkMin; NewLink < ThisLink; NewLink++) { 146 if ((readb(&PktCmdP->RouteTopology[ThisLink].Unit) == readb(&PktCmdP->RouteTopology[NewLink].Unit)) && (readb(&PktCmdP->RouteTopology[ThisLink].Link) == readb(&PktCmdP->RouteTopology[NewLink].Link))) { 147 Lies++; 148 } 149 } 150 } 151 152 if (Lies) { 153 rio_dprintk(RIO_DEBUG_ROUTE, "LIES! DAMN LIES! %d LIES!\n", Lies); 154 rio_dprintk(RIO_DEBUG_ROUTE, "%d:%c %d:%c %d:%c %d:%c\n", 155 readb(&PktCmdP->RouteTopology[0].Unit), 156 'A' + readb(&PktCmdP->RouteTopology[0].Link), 157 readb(&PktCmdP->RouteTopology[1].Unit), 158 'A' + readb(&PktCmdP->RouteTopology[1].Link), readb(&PktCmdP->RouteTopology[2].Unit), 'A' + readb(&PktCmdP->RouteTopology[2].Link), readb(&PktCmdP->RouteTopology[3].Unit), 'A' + readb(&PktCmdP->RouteTopology[3].Link)); 159 return 1; 160 } 161 162 /* 163 ** now, process each link. 164 */ 165 for (ThisLink = ThisLinkMin; ThisLink <= ThisLinkMax; ThisLink++) { 166 /* 167 ** this is what it was connected to 168 */ 169 OldUnit = TopP[ThisLink].Unit; 170 OldLink = TopP[ThisLink].Link; 171 172 /* 173 ** this is what it is now connected to 174 */ 175 NewUnit = readb(&PktCmdP->RouteTopology[ThisLink].Unit); 176 NewLink = readb(&PktCmdP->RouteTopology[ThisLink].Link); 177 178 if (OldUnit != NewUnit || OldLink != NewLink) { 179 /* 180 ** something has changed! 181 */ 182 183 if (NewUnit > MAX_RUP && NewUnit != ROUTE_DISCONNECT && NewUnit != ROUTE_NO_ID && NewUnit != ROUTE_INTERCONNECT) { 184 rio_dprintk(RIO_DEBUG_ROUTE, "I have a link from %s %s to unit %d:%d - I don't like it.\n", MyType, MyName, NewUnit, NewLink); 185 } else { 186 /* 187 ** put the new values in 188 */ 189 TopP[ThisLink].Unit = NewUnit; 190 TopP[ThisLink].Link = NewLink; 191 192 RIOSetChange(p); 193 194 if (OldUnit <= MAX_RUP) { 195 /* 196 ** If something has become bust, then re-enable them messages 197 */ 198 if (!p->RIONoMessage) 199 RIOConCon(p, HostP, ThisUnit, ThisLink, OldUnit, OldLink, DISCONNECT); 200 } 201 202 if ((NewUnit <= MAX_RUP) && !p->RIONoMessage) 203 RIOConCon(p, HostP, ThisUnit, ThisLink, NewUnit, NewLink, CONNECT); 204 205 if (NewUnit == ROUTE_NO_ID) 206 rio_dprintk(RIO_DEBUG_ROUTE, "%s %s (%c) is connected to an unconfigured unit.\n", MyType, MyName, 'A' + ThisLink); 207 208 if (NewUnit == ROUTE_INTERCONNECT) { 209 if (!p->RIONoMessage) 210 printk(KERN_DEBUG "rio: %s '%s' (%c) is connected to another network.\n", MyType, MyName, 'A' + ThisLink); 211 } 212 213 /* 214 ** perform an update for 'the other end', so that these messages 215 ** only appears once. Only disconnect the other end if it is pointing 216 ** at us! 217 */ 218 if (OldUnit == HOST_ID) { 219 if (HostP->Topology[OldLink].Unit == ThisUnit && HostP->Topology[OldLink].Link == ThisLink) { 220 rio_dprintk(RIO_DEBUG_ROUTE, "SETTING HOST (%c) TO DISCONNECTED!\n", OldLink + 'A'); 221 HostP->Topology[OldLink].Unit = ROUTE_DISCONNECT; 222 HostP->Topology[OldLink].Link = NO_LINK; 223 } else { 224 rio_dprintk(RIO_DEBUG_ROUTE, "HOST(%c) WAS NOT CONNECTED TO %s (%c)!\n", OldLink + 'A', HostP->Mapping[ThisUnit - 1].Name, ThisLink + 'A'); 225 } 226 } else if (OldUnit <= MAX_RUP) { 227 if (HostP->Mapping[OldUnit - 1].Topology[OldLink].Unit == ThisUnit && HostP->Mapping[OldUnit - 1].Topology[OldLink].Link == ThisLink) { 228 rio_dprintk(RIO_DEBUG_ROUTE, "SETTING RTA %s (%c) TO DISCONNECTED!\n", HostP->Mapping[OldUnit - 1].Name, OldLink + 'A'); 229 HostP->Mapping[OldUnit - 1].Topology[OldLink].Unit = ROUTE_DISCONNECT; 230 HostP->Mapping[OldUnit - 1].Topology[OldLink].Link = NO_LINK; 231 } else { 232 rio_dprintk(RIO_DEBUG_ROUTE, "RTA %s (%c) WAS NOT CONNECTED TO %s (%c)\n", HostP->Mapping[OldUnit - 1].Name, OldLink + 'A', HostP->Mapping[ThisUnit - 1].Name, ThisLink + 'A'); 233 } 234 } 235 if (NewUnit == HOST_ID) { 236 rio_dprintk(RIO_DEBUG_ROUTE, "MARKING HOST (%c) CONNECTED TO %s (%c)\n", NewLink + 'A', MyName, ThisLink + 'A'); 237 HostP->Topology[NewLink].Unit = ThisUnit; 238 HostP->Topology[NewLink].Link = ThisLink; 239 } else if (NewUnit <= MAX_RUP) { 240 rio_dprintk(RIO_DEBUG_ROUTE, "MARKING RTA %s (%c) CONNECTED TO %s (%c)\n", HostP->Mapping[NewUnit - 1].Name, NewLink + 'A', MyName, ThisLink + 'A'); 241 HostP->Mapping[NewUnit - 1].Topology[NewLink].Unit = ThisUnit; 242 HostP->Mapping[NewUnit - 1].Topology[NewLink].Link = ThisLink; 243 } 244 } 245 RIOSetChange(p); 246 RIOCheckIsolated(p, HostP, OldUnit); 247 } 248 } 249 return 1; 250 } 251 252 /* 253 ** The only other command we recognise is a route_request command 254 */ 255 if (readb(&PktCmdP->Command) != ROUTE_REQUEST) { 256 rio_dprintk(RIO_DEBUG_ROUTE, "Unknown command %d received on rup %d host %p ROUTE_RUP\n", readb(&PktCmdP->Command), Rup, HostP); 257 return 1; 258 } 259 260 RtaUniq = (readb(&PktCmdP->UniqNum[0])) + (readb(&PktCmdP->UniqNum[1]) << 8) + (readb(&PktCmdP->UniqNum[2]) << 16) + (readb(&PktCmdP->UniqNum[3]) << 24); 261 262 /* 263 ** Determine if 8 or 16 port RTA 264 */ 265 RtaType = GetUnitType(RtaUniq); 266 267 rio_dprintk(RIO_DEBUG_ROUTE, "Received a request for an ID for serial number %x\n", RtaUniq); 268 269 Mod = readb(&PktCmdP->ModuleTypes); 270 Mod1 = LONYBLE(Mod); 271 if (RtaType == TYPE_RTA16) { 272 /* 273 ** Only one ident is set for a 16 port RTA. To make compatible 274 ** with 8 port, set 2nd ident in Mod2 to the same as Mod1. 275 */ 276 Mod2 = Mod1; 277 rio_dprintk(RIO_DEBUG_ROUTE, "Backplane type is %s (all ports)\n", p->RIOModuleTypes[Mod1].Name); 278 } else { 279 Mod2 = HINYBLE(Mod); 280 rio_dprintk(RIO_DEBUG_ROUTE, "Module types are %s (ports 0-3) and %s (ports 4-7)\n", p->RIOModuleTypes[Mod1].Name, p->RIOModuleTypes[Mod2].Name); 281 } 282 283 /* 284 ** try to unhook a command block from the command free list. 285 */ 286 if (!(CmdBlkP = RIOGetCmdBlk())) { 287 rio_dprintk(RIO_DEBUG_ROUTE, "No command blocks to route RTA! come back later.\n"); 288 return 0; 289 } 290 291 /* 292 ** Fill in the default info on the command block 293 */ 294 CmdBlkP->Packet.dest_unit = Rup; 295 CmdBlkP->Packet.dest_port = ROUTE_RUP; 296 CmdBlkP->Packet.src_unit = HOST_ID; 297 CmdBlkP->Packet.src_port = ROUTE_RUP; 298 CmdBlkP->Packet.len = PKT_CMD_BIT | 1; 299 CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL; 300 PktReplyP = (struct PktCmd_M *) CmdBlkP->Packet.data; 301 302 if (!RIOBootOk(p, HostP, RtaUniq)) { 303 rio_dprintk(RIO_DEBUG_ROUTE, "RTA %x tried to get an ID, but does not belong - FOAD it!\n", RtaUniq); 304 PktReplyP->Command = ROUTE_FOAD; 305 memcpy(PktReplyP->CommandText, "RT_FOAD", 7); 306 RIOQueueCmdBlk(HostP, Rup, CmdBlkP); 307 return 1; 308 } 309 310 /* 311 ** Check to see if the RTA is configured for this host 312 */ 313 for (ThisUnit = 0; ThisUnit < MAX_RUP; ThisUnit++) { 314 rio_dprintk(RIO_DEBUG_ROUTE, "Entry %d Flags=%s %s UniqueNum=0x%x\n", 315 ThisUnit, HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE ? "Slot-In-Use" : "Not In Use", HostP->Mapping[ThisUnit].Flags & SLOT_TENTATIVE ? "Slot-Tentative" : "Not Tentative", HostP->Mapping[ThisUnit].RtaUniqueNum); 316 317 /* 318 ** We have an entry for it. 319 */ 320 if ((HostP->Mapping[ThisUnit].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) && (HostP->Mapping[ThisUnit].RtaUniqueNum == RtaUniq)) { 321 if (RtaType == TYPE_RTA16) { 322 ThisUnit2 = HostP->Mapping[ThisUnit].ID2 - 1; 323 rio_dprintk(RIO_DEBUG_ROUTE, "Found unit 0x%x at slots %d+%d\n", RtaUniq, ThisUnit, ThisUnit2); 324 } else 325 rio_dprintk(RIO_DEBUG_ROUTE, "Found unit 0x%x at slot %d\n", RtaUniq, ThisUnit); 326 /* 327 ** If we have no knowledge of booting it, then the host has 328 ** been re-booted, and so we must kill the RTA, so that it 329 ** will be booted again (potentially with new bins) 330 ** and it will then re-ask for an ID, which we will service. 331 */ 332 if ((HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) && !(HostP->Mapping[ThisUnit].Flags & RTA_BOOTED)) { 333 if (!(HostP->Mapping[ThisUnit].Flags & MSG_DONE)) { 334 if (!p->RIONoMessage) 335 printk(KERN_DEBUG "rio: RTA '%s' is being updated.\n", HostP->Mapping[ThisUnit].Name); 336 HostP->Mapping[ThisUnit].Flags |= MSG_DONE; 337 } 338 PktReplyP->Command = ROUTE_FOAD; 339 memcpy(PktReplyP->CommandText, "RT_FOAD", 7); 340 RIOQueueCmdBlk(HostP, Rup, CmdBlkP); 341 return 1; 342 } 343 344 /* 345 ** Send the ID (entry) to this RTA. The ID number is implicit as 346 ** the offset into the table. It is worth noting at this stage 347 ** that offset zero in the table contains the entries for the 348 ** RTA with ID 1!!!! 349 */ 350 PktReplyP->Command = ROUTE_ALLOCATE; 351 PktReplyP->IDNum = ThisUnit + 1; 352 if (RtaType == TYPE_RTA16) { 353 if (HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) 354 /* 355 ** Adjust the phb and tx pkt dest_units for 2nd block of 8 356 ** only if the RTA has ports associated (SLOT_IN_USE) 357 */ 358 RIOFixPhbs(p, HostP, ThisUnit2); 359 PktReplyP->IDNum2 = ThisUnit2 + 1; 360 rio_dprintk(RIO_DEBUG_ROUTE, "RTA '%s' has been allocated IDs %d+%d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2); 361 } else { 362 PktReplyP->IDNum2 = ROUTE_NO_ID; 363 rio_dprintk(RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum); 364 } 365 memcpy(PktReplyP->CommandText, "RT_ALLOCAT", 10); 366 367 RIOQueueCmdBlk(HostP, Rup, CmdBlkP); 368 369 /* 370 ** If this is a freshly booted RTA, then we need to re-open 371 ** the ports, if any where open, so that data may once more 372 ** flow around the system! 373 */ 374 if ((HostP->Mapping[ThisUnit].Flags & RTA_NEWBOOT) && (HostP->Mapping[ThisUnit].SysPort != NO_PORT)) { 375 /* 376 ** look at the ports associated with this beast and 377 ** see if any where open. If they was, then re-open 378 ** them, using the info from the tty flags. 379 */ 380 for (port = 0; port < PORTS_PER_RTA; port++) { 381 PortP = p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]; 382 if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) { 383 rio_dprintk(RIO_DEBUG_ROUTE, "Re-opened this port\n"); 384 rio_spin_lock_irqsave(&PortP->portSem, flags); 385 PortP->MagicFlags |= MAGIC_REBOOT; 386 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 387 } 388 } 389 if (RtaType == TYPE_RTA16) { 390 for (port = 0; port < PORTS_PER_RTA; port++) { 391 PortP = p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]; 392 if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) { 393 rio_dprintk(RIO_DEBUG_ROUTE, "Re-opened this port\n"); 394 rio_spin_lock_irqsave(&PortP->portSem, flags); 395 PortP->MagicFlags |= MAGIC_REBOOT; 396 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 397 } 398 } 399 } 400 } 401 402 /* 403 ** keep a copy of the module types! 404 */ 405 HostP->UnixRups[ThisUnit].ModTypes = Mod; 406 if (RtaType == TYPE_RTA16) 407 HostP->UnixRups[ThisUnit2].ModTypes = Mod; 408 409 /* 410 ** If either of the modules on this unit is read-only or write-only 411 ** or none-xprint, then we need to transfer that info over to the 412 ** relevant ports. 413 */ 414 if (HostP->Mapping[ThisUnit].SysPort != NO_PORT) { 415 for (port = 0; port < PORTS_PER_MODULE; port++) { 416 p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK; 417 p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port]; 418 p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK; 419 p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port]; 420 } 421 if (RtaType == TYPE_RTA16) { 422 for (port = 0; port < PORTS_PER_MODULE; port++) { 423 p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK; 424 p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port]; 425 p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK; 426 p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port]; 427 } 428 } 429 } 430 431 /* 432 ** Job done, get on with the interrupts! 433 */ 434 return 1; 435 } 436 } 437 /* 438 ** There is no table entry for this RTA at all. 439 ** 440 ** Lets check to see if we actually booted this unit - if not, 441 ** then we reset it and it will go round the loop of being booted 442 ** we can then worry about trying to fit it into the table. 443 */ 444 for (ThisUnit = 0; ThisUnit < HostP->NumExtraBooted; ThisUnit++) 445 if (HostP->ExtraUnits[ThisUnit] == RtaUniq) 446 break; 447 if (ThisUnit == HostP->NumExtraBooted && ThisUnit != MAX_EXTRA_UNITS) { 448 /* 449 ** if the unit wasn't in the table, and the table wasn't full, then 450 ** we reset the unit, because we didn't boot it. 451 ** However, if the table is full, it could be that we did boot 452 ** this unit, and so we won't reboot it, because it isn't really 453 ** all that disasterous to keep the old bins in most cases. This 454 ** is a rather tacky feature, but we are on the edge of reallity 455 ** here, because the implication is that someone has connected 456 ** 16+MAX_EXTRA_UNITS onto one host. 457 */ 458 static int UnknownMesgDone = 0; 459 460 if (!UnknownMesgDone) { 461 if (!p->RIONoMessage) 462 printk(KERN_DEBUG "rio: One or more unknown RTAs are being updated.\n"); 463 UnknownMesgDone = 1; 464 } 465 466 PktReplyP->Command = ROUTE_FOAD; 467 memcpy(PktReplyP->CommandText, "RT_FOAD", 7); 468 } else { 469 /* 470 ** we did boot it (as an extra), and there may now be a table 471 ** slot free (because of a delete), so we will try to make 472 ** a tentative entry for it, so that the configurator can see it 473 ** and fill in the details for us. 474 */ 475 if (RtaType == TYPE_RTA16) { 476 if (RIOFindFreeID(p, HostP, &ThisUnit, &ThisUnit2) == 0) { 477 RIODefaultName(p, HostP, ThisUnit); 478 rio_fill_host_slot(ThisUnit, ThisUnit2, RtaUniq, HostP); 479 } 480 } else { 481 if (RIOFindFreeID(p, HostP, &ThisUnit, NULL) == 0) { 482 RIODefaultName(p, HostP, ThisUnit); 483 rio_fill_host_slot(ThisUnit, 0, RtaUniq, HostP); 484 } 485 } 486 PktReplyP->Command = ROUTE_USED; 487 memcpy(PktReplyP->CommandText, "RT_USED", 7); 488 } 489 RIOQueueCmdBlk(HostP, Rup, CmdBlkP); 490 return 1; 491} 492 493 494void RIOFixPhbs(struct rio_info *p, struct Host *HostP, unsigned int unit) 495{ 496 unsigned short link, port; 497 struct Port *PortP; 498 unsigned long flags; 499 int PortN = HostP->Mapping[unit].SysPort; 500 501 rio_dprintk(RIO_DEBUG_ROUTE, "RIOFixPhbs unit %d sysport %d\n", unit, PortN); 502 503 if (PortN != -1) { 504 unsigned short dest_unit = HostP->Mapping[unit].ID2; 505 506 /* 507 ** Get the link number used for the 1st 8 phbs on this unit. 508 */ 509 PortP = p->RIOPortp[HostP->Mapping[dest_unit - 1].SysPort]; 510 511 link = readw(&PortP->PhbP->link); 512 513 for (port = 0; port < PORTS_PER_RTA; port++, PortN++) { 514 unsigned short dest_port = port + 8; 515 u16 __iomem *TxPktP; 516 struct PKT __iomem *Pkt; 517 518 PortP = p->RIOPortp[PortN]; 519 520 rio_spin_lock_irqsave(&PortP->portSem, flags); 521 /* 522 ** If RTA is not powered on, the tx packets will be 523 ** unset, so go no further. 524 */ 525 if (!PortP->TxStart) { 526 rio_dprintk(RIO_DEBUG_ROUTE, "Tx pkts not set up yet\n"); 527 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 528 break; 529 } 530 531 /* 532 ** For the second slot of a 16 port RTA, the driver needs to 533 ** sort out the phb to port mappings. The dest_unit for this 534 ** group of 8 phbs is set to the dest_unit of the accompanying 535 ** 8 port block. The dest_port of the second unit is set to 536 ** be in the range 8-15 (i.e. 8 is added). Thus, for a 16 port 537 ** RTA with IDs 5 and 6, traffic bound for port 6 of unit 6 538 ** (being the second map ID) will be sent to dest_unit 5, port 539 ** 14. When this RTA is deleted, dest_unit for ID 6 will be 540 ** restored, and the dest_port will be reduced by 8. 541 ** Transmit packets also have a destination field which needs 542 ** adjusting in the same manner. 543 ** Note that the unit/port bytes in 'dest' are swapped. 544 ** We also need to adjust the phb and rup link numbers for the 545 ** second block of 8 ttys. 546 */ 547 for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) { 548 /* 549 ** *TxPktP is the pointer to the transmit packet on the host 550 ** card. This needs to be translated into a 32 bit pointer 551 ** so it can be accessed from the driver. 552 */ 553 Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(TxPktP)); 554 555 /* 556 ** If the packet is used, reset it. 557 */ 558 Pkt = (struct PKT __iomem *) ((unsigned long) Pkt & ~PKT_IN_USE); 559 writeb(dest_unit, &Pkt->dest_unit); 560 writeb(dest_port, &Pkt->dest_port); 561 } 562 rio_dprintk(RIO_DEBUG_ROUTE, "phb dest: Old %x:%x New %x:%x\n", readw(&PortP->PhbP->destination) & 0xff, (readw(&PortP->PhbP->destination) >> 8) & 0xff, dest_unit, dest_port); 563 writew(dest_unit + (dest_port << 8), &PortP->PhbP->destination); 564 writew(link, &PortP->PhbP->link); 565 566 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 567 } 568 /* 569 ** Now make sure the range of ports to be serviced includes 570 ** the 2nd 8 on this 16 port RTA. 571 */ 572 if (link > 3) 573 return; 574 if (((unit * 8) + 7) > readw(&HostP->LinkStrP[link].last_port)) { 575 rio_dprintk(RIO_DEBUG_ROUTE, "last port on host link %d: %d\n", link, (unit * 8) + 7); 576 writew((unit * 8) + 7, &HostP->LinkStrP[link].last_port); 577 } 578 } 579} 580 581/* 582** Check to see if the new disconnection has isolated this unit. 583** If it has, then invalidate all its link information, and tell 584** the world about it. This is done to ensure that the configurator 585** only gets up-to-date information about what is going on. 586*/ 587static int RIOCheckIsolated(struct rio_info *p, struct Host *HostP, unsigned int UnitId) 588{ 589 unsigned long flags; 590 rio_spin_lock_irqsave(&HostP->HostLock, flags); 591 592 if (RIOCheck(HostP, UnitId)) { 593 rio_dprintk(RIO_DEBUG_ROUTE, "Unit %d is NOT isolated\n", UnitId); 594 rio_spin_unlock_irqrestore(&HostP->HostLock, flags); 595 return (0); 596 } 597 598 RIOIsolate(p, HostP, UnitId); 599 RIOSetChange(p); 600 rio_spin_unlock_irqrestore(&HostP->HostLock, flags); 601 return 1; 602} 603 604/* 605** Invalidate all the link interconnectivity of this unit, and of 606** all the units attached to it. This will mean that the entire 607** subnet will re-introduce itself. 608*/ 609static int RIOIsolate(struct rio_info *p, struct Host *HostP, unsigned int UnitId) 610{ 611 unsigned int link, unit; 612 613 UnitId--; /* this trick relies on the Unit Id being UNSIGNED! */ 614 615 if (UnitId >= MAX_RUP) /* dontcha just lurv unsigned maths! */ 616 return (0); 617 618 if (HostP->Mapping[UnitId].Flags & BEEN_HERE) 619 return (0); 620 621 HostP->Mapping[UnitId].Flags |= BEEN_HERE; 622 623 if (p->RIOPrintDisabled == DO_PRINT) 624 rio_dprintk(RIO_DEBUG_ROUTE, "RIOMesgIsolated %s", HostP->Mapping[UnitId].Name); 625 626 for (link = 0; link < LINKS_PER_UNIT; link++) { 627 unit = HostP->Mapping[UnitId].Topology[link].Unit; 628 HostP->Mapping[UnitId].Topology[link].Unit = ROUTE_DISCONNECT; 629 HostP->Mapping[UnitId].Topology[link].Link = NO_LINK; 630 RIOIsolate(p, HostP, unit); 631 } 632 HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; 633 return 1; 634} 635 636static int RIOCheck(struct Host *HostP, unsigned int UnitId) 637{ 638 unsigned char link; 639 640/* rio_dprint(RIO_DEBUG_ROUTE, ("Check to see if unit %d has a route to the host\n",UnitId)); */ 641 rio_dprintk(RIO_DEBUG_ROUTE, "RIOCheck : UnitID = %d\n", UnitId); 642 643 if (UnitId == HOST_ID) { 644 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is NOT isolated - it IS the host!\n", UnitId)); */ 645 return 1; 646 } 647 648 UnitId--; 649 650 if (UnitId >= MAX_RUP) { 651 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d - ignored.\n", UnitId)); */ 652 return 0; 653 } 654 655 for (link = 0; link < LINKS_PER_UNIT; link++) { 656 if (HostP->Mapping[UnitId].Topology[link].Unit == HOST_ID) { 657 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected directly to host via link (%c).\n", 658 UnitId, 'A'+link)); */ 659 return 1; 660 } 661 } 662 663 if (HostP->Mapping[UnitId].Flags & BEEN_HERE) { 664 /* rio_dprint(RIO_DEBUG_ROUTE, ("Been to Unit %d before - ignoring\n", UnitId)); */ 665 return 0; 666 } 667 668 HostP->Mapping[UnitId].Flags |= BEEN_HERE; 669 670 for (link = 0; link < LINKS_PER_UNIT; link++) { 671 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d check link (%c)\n", UnitId,'A'+link)); */ 672 if (RIOCheck(HostP, HostP->Mapping[UnitId].Topology[link].Unit)) { 673 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected to something that knows the host via link (%c)\n", UnitId,link+'A')); */ 674 HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; 675 return 1; 676 } 677 } 678 679 HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; 680 681 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d DOESNT KNOW THE HOST!\n", UnitId)); */ 682 683 return 0; 684} 685 686/* 687** Returns the type of unit (host, 16/8 port RTA) 688*/ 689 690unsigned int GetUnitType(unsigned int Uniq) 691{ 692 switch ((Uniq >> 28) & 0xf) { 693 case RIO_AT: 694 case RIO_MCA: 695 case RIO_EISA: 696 case RIO_PCI: 697 rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: Host\n"); 698 return (TYPE_HOST); 699 case RIO_RTA_16: 700 rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: 16 port RTA\n"); 701 return (TYPE_RTA16); 702 case RIO_RTA: 703 rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: 8 port RTA\n"); 704 return (TYPE_RTA8); 705 default: 706 rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: Unrecognised\n"); 707 return (99); 708 } 709} 710 711int RIOSetChange(struct rio_info *p) 712{ 713 if (p->RIOQuickCheck != NOT_CHANGED) 714 return (0); 715 p->RIOQuickCheck = CHANGED; 716 if (p->RIOSignalProcess) { 717 rio_dprintk(RIO_DEBUG_ROUTE, "Send SIG-HUP"); 718 /* 719 psignal( RIOSignalProcess, SIGHUP ); 720 */ 721 } 722 return (0); 723} 724 725static void RIOConCon(struct rio_info *p, 726 struct Host *HostP, 727 unsigned int FromId, 728 unsigned int FromLink, 729 unsigned int ToId, 730 unsigned int ToLink, 731 int Change) 732{ 733 char *FromName; 734 char *FromType; 735 char *ToName; 736 char *ToType; 737 unsigned int tp; 738 739/* 740** 15.10.1998 ARG - ESIL 0759 741** (Part) fix for port being trashed when opened whilst RTA "disconnected" 742** 743** What's this doing in here anyway ? 744** It was causing the port to be 'unmapped' if opened whilst RTA "disconnected" 745** 746** 09.12.1998 ARG - ESIL 0776 - part fix 747** Okay, We've found out what this was all about now ! 748** Someone had botched this to use RIOHalted to indicated the number of RTAs 749** 'disconnected'. The value in RIOHalted was then being used in the 750** 'RIO_QUICK_CHECK' ioctl. A none zero value indicating that a least one RTA 751** is 'disconnected'. The change was put in to satisfy a customer's needs. 752** Having taken this bit of code out 'RIO_QUICK_CHECK' now no longer works for 753** the customer. 754** 755 if (Change == CONNECT) { 756 if (p->RIOHalted) p->RIOHalted --; 757 } 758 else { 759 p->RIOHalted ++; 760 } 761** 762** So - we need to implement it slightly differently - a new member of the 763** rio_info struct - RIORtaDisCons (RIO RTA connections) keeps track of RTA 764** connections and disconnections. 765*/ 766 if (Change == CONNECT) { 767 if (p->RIORtaDisCons) 768 p->RIORtaDisCons--; 769 } else { 770 p->RIORtaDisCons++; 771 } 772 773 if (p->RIOPrintDisabled == DONT_PRINT) 774 return; 775 776 if (FromId > ToId) { 777 tp = FromId; 778 FromId = ToId; 779 ToId = tp; 780 tp = FromLink; 781 FromLink = ToLink; 782 ToLink = tp; 783 } 784 785 FromName = FromId ? HostP->Mapping[FromId - 1].Name : HostP->Name; 786 FromType = FromId ? "RTA" : "HOST"; 787 ToName = ToId ? HostP->Mapping[ToId - 1].Name : HostP->Name; 788 ToType = ToId ? "RTA" : "HOST"; 789 790 rio_dprintk(RIO_DEBUG_ROUTE, "Link between %s '%s' (%c) and %s '%s' (%c) %s.\n", FromType, FromName, 'A' + FromLink, ToType, ToName, 'A' + ToLink, (Change == CONNECT) ? "established" : "disconnected"); 791 printk(KERN_DEBUG "rio: Link between %s '%s' (%c) and %s '%s' (%c) %s.\n", FromType, FromName, 'A' + FromLink, ToType, ToName, 'A' + ToLink, (Change == CONNECT) ? "established" : "disconnected"); 792} 793 794/* 795** RIORemoveFromSavedTable : 796** 797** Delete and RTA entry from the saved table given to us 798** by the configuration program. 799*/ 800static int RIORemoveFromSavedTable(struct rio_info *p, struct Map *pMap) 801{ 802 int entry; 803 804 /* 805 ** We loop for all entries even after finding an entry and 806 ** zeroing it because we may have two entries to delete if 807 ** it's a 16 port RTA. 808 */ 809 for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) { 810 if (p->RIOSavedTable[entry].RtaUniqueNum == pMap->RtaUniqueNum) { 811 memset(&p->RIOSavedTable[entry], 0, sizeof(struct Map)); 812 } 813 } 814 return 0; 815} 816 817 818/* 819** RIOCheckDisconnected : 820** 821** Scan the unit links to and return zero if the unit is completely 822** disconnected. 823*/ 824static int RIOFreeDisconnected(struct rio_info *p, struct Host *HostP, int unit) 825{ 826 int link; 827 828 829 rio_dprintk(RIO_DEBUG_ROUTE, "RIOFreeDisconnect unit %d\n", unit); 830 /* 831 ** If the slot is tentative and does not belong to the 832 ** second half of a 16 port RTA then scan to see if 833 ** is disconnected. 834 */ 835 for (link = 0; link < LINKS_PER_UNIT; link++) { 836 if (HostP->Mapping[unit].Topology[link].Unit != ROUTE_DISCONNECT) 837 break; 838 } 839 840 /* 841 ** If not all links are disconnected then we can forget about it. 842 */ 843 if (link < LINKS_PER_UNIT) 844 return 1; 845 846#ifdef NEED_TO_FIX_THIS 847 /* Ok so all the links are disconnected. But we may have only just 848 ** made this slot tentative and not yet received a topology update. 849 ** Lets check how long ago we made it tentative. 850 */ 851 rio_dprintk(RIO_DEBUG_ROUTE, "Just about to check LBOLT on entry %d\n", unit); 852 if (drv_getparm(LBOLT, (ulong_t *) & current_time)) 853 rio_dprintk(RIO_DEBUG_ROUTE, "drv_getparm(LBOLT,....) Failed.\n"); 854 855 elapse_time = current_time - TentTime[unit]; 856 rio_dprintk(RIO_DEBUG_ROUTE, "elapse %d = current %d - tent %d (%d usec)\n", elapse_time, current_time, TentTime[unit], drv_hztousec(elapse_time)); 857 if (drv_hztousec(elapse_time) < WAIT_TO_FINISH) { 858 rio_dprintk(RIO_DEBUG_ROUTE, "Skipping slot %d, not timed out yet %d\n", unit, drv_hztousec(elapse_time)); 859 return 1; 860 } 861#endif 862 863 /* 864 ** We have found an usable slot. 865 ** If it is half of a 16 port RTA then delete the other half. 866 */ 867 if (HostP->Mapping[unit].ID2 != 0) { 868 int nOther = (HostP->Mapping[unit].ID2) - 1; 869 870 rio_dprintk(RIO_DEBUG_ROUTE, "RioFreedis second slot %d.\n", nOther); 871 memset(&HostP->Mapping[nOther], 0, sizeof(struct Map)); 872 } 873 RIORemoveFromSavedTable(p, &HostP->Mapping[unit]); 874 875 return 0; 876} 877 878 879/* 880** RIOFindFreeID : 881** 882** This function scans the given host table for either one 883** or two free unit ID's. 884*/ 885 886int RIOFindFreeID(struct rio_info *p, struct Host *HostP, unsigned int * pID1, unsigned int * pID2) 887{ 888 int unit, tempID; 889 890 /* 891 ** Initialise the ID's to MAX_RUP. 892 ** We do this to make the loop for setting the ID's as simple as 893 ** possible. 894 */ 895 *pID1 = MAX_RUP; 896 if (pID2 != NULL) 897 *pID2 = MAX_RUP; 898 899 /* 900 ** Scan all entries of the host mapping table for free slots. 901 ** We scan for free slots first and then if that is not successful 902 ** we start all over again looking for tentative slots we can re-use. 903 */ 904 for (unit = 0; unit < MAX_RUP; unit++) { 905 rio_dprintk(RIO_DEBUG_ROUTE, "Scanning unit %d\n", unit); 906 /* 907 ** If the flags are zero then the slot is empty. 908 */ 909 if (HostP->Mapping[unit].Flags == 0) { 910 rio_dprintk(RIO_DEBUG_ROUTE, " This slot is empty.\n"); 911 /* 912 ** If we haven't allocated the first ID then do it now. 913 */ 914 if (*pID1 == MAX_RUP) { 915 rio_dprintk(RIO_DEBUG_ROUTE, "Make tentative entry for first unit %d\n", unit); 916 *pID1 = unit; 917 918 /* 919 ** If the second ID is not needed then we can return 920 ** now. 921 */ 922 if (pID2 == NULL) 923 return 0; 924 } else { 925 /* 926 ** Allocate the second slot and return. 927 */ 928 rio_dprintk(RIO_DEBUG_ROUTE, "Make tentative entry for second unit %d\n", unit); 929 *pID2 = unit; 930 return 0; 931 } 932 } 933 } 934 935 /* 936 ** If we manage to come out of the free slot loop then we 937 ** need to start all over again looking for tentative slots 938 ** that we can re-use. 939 */ 940 rio_dprintk(RIO_DEBUG_ROUTE, "Starting to scan for tentative slots\n"); 941 for (unit = 0; unit < MAX_RUP; unit++) { 942 if (((HostP->Mapping[unit].Flags & SLOT_TENTATIVE) || (HostP->Mapping[unit].Flags == 0)) && !(HostP->Mapping[unit].Flags & RTA16_SECOND_SLOT)) { 943 rio_dprintk(RIO_DEBUG_ROUTE, " Slot %d looks promising.\n", unit); 944 945 if (unit == *pID1) { 946 rio_dprintk(RIO_DEBUG_ROUTE, " No it isn't, its the 1st half\n"); 947 continue; 948 } 949 950 /* 951 ** Slot is Tentative or Empty, but not a tentative second 952 ** slot of a 16 porter. 953 ** Attempt to free up this slot (and its parnter if 954 ** it is a 16 port slot. The second slot will become 955 ** empty after a call to RIOFreeDisconnected so thats why 956 ** we look for empty slots above as well). 957 */ 958 if (HostP->Mapping[unit].Flags != 0) 959 if (RIOFreeDisconnected(p, HostP, unit) != 0) 960 continue; 961 /* 962 ** If we haven't allocated the first ID then do it now. 963 */ 964 if (*pID1 == MAX_RUP) { 965 rio_dprintk(RIO_DEBUG_ROUTE, "Grab tentative entry for first unit %d\n", unit); 966 *pID1 = unit; 967 968 /* 969 ** Clear out this slot now that we intend to use it. 970 */ 971 memset(&HostP->Mapping[unit], 0, sizeof(struct Map)); 972 973 /* 974 ** If the second ID is not needed then we can return 975 ** now. 976 */ 977 if (pID2 == NULL) 978 return 0; 979 } else { 980 /* 981 ** Allocate the second slot and return. 982 */ 983 rio_dprintk(RIO_DEBUG_ROUTE, "Grab tentative/empty entry for second unit %d\n", unit); 984 *pID2 = unit; 985 986 /* 987 ** Clear out this slot now that we intend to use it. 988 */ 989 memset(&HostP->Mapping[unit], 0, sizeof(struct Map)); 990 991 /* At this point under the right(wrong?) conditions 992 ** we may have a first unit ID being higher than the 993 ** second unit ID. This is a bad idea if we are about 994 ** to fill the slots with a 16 port RTA. 995 ** Better check and swap them over. 996 */ 997 998 if (*pID1 > *pID2) { 999 rio_dprintk(RIO_DEBUG_ROUTE, "Swapping IDS %d %d\n", *pID1, *pID2); 1000 tempID = *pID1; 1001 *pID1 = *pID2; 1002 *pID2 = tempID; 1003 } 1004 return 0; 1005 } 1006 } 1007 } 1008 1009 /* 1010 ** If we manage to get to the end of the second loop then we 1011 ** can give up and return a failure. 1012 */ 1013 return 1; 1014} 1015 1016 1017/* 1018** The link switch scenario. 1019** 1020** Rta Wun (A) is connected to Tuw (A). 1021** The tables are all up to date, and the system is OK. 1022** 1023** If Wun (A) is now moved to Wun (B) before Wun (A) can 1024** become disconnected, then the follow happens: 1025** 1026** Tuw (A) spots the change of unit:link at the other end 1027** of its link and Tuw sends a topology packet reflecting 1028** the change: Tuw (A) now disconnected from Wun (A), and 1029** this is closely followed by a packet indicating that 1030** Tuw (A) is now connected to Wun (B). 1031** 1032** Wun (B) will spot that it has now become connected, and 1033** Wun will send a topology packet, which indicates that 1034** both Wun (A) and Wun (B) is connected to Tuw (A). 1035** 1036** Eventually Wun (A) realises that it is now disconnected 1037** and Wun will send out a topology packet indicating that 1038** Wun (A) is now disconnected. 1039*/ 1040