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