Exemple #1
0
static irqreturn_t ni52_interrupt(int irq, void *dev_id)
{
	struct net_device *dev = dev_id;
	unsigned int stat;
	int cnt = 0;
	struct priv *p;

	p = (struct priv *) dev->priv;

	if (debuglevel > 1)
		printk("I");

	spin_lock(&p->spinlock);

	wait_for_scb_cmd(dev); /* wait for last command	*/

	while ((stat = readb(&p->scb->cus) & STAT_MASK)) {
		writeb(stat, &p->scb->cmd_cuc);
		ni_attn586();

		if (stat & STAT_FR)	 /* received a frame */
			ni52_rcv_int(dev);

		if (stat & STAT_RNR) { /* RU went 'not ready' */
			printk("(R)");
			if (readb(&p->scb->rus) & RU_SUSPEND) {
				/* special case: RU_SUSPEND */
				wait_for_scb_cmd(dev);
				writeb(RUC_RESUME, &p->scb->cmd_ruc);
				ni_attn586();
				wait_for_scb_cmd_ruc(dev);
			} else {
				printk(KERN_ERR "%s: Receiver-Unit went 'NOT READY': %04x/%02x.\n",
					dev->name, stat, readb(&p->scb->rus));
				ni52_rnr_int(dev);
			}
		}

		/* Command with I-bit set complete */
		if (stat & STAT_CX)
			 ni52_xmt_int(dev);

#ifndef NO_NOPCOMMANDS
		if (stat & STAT_CNA) {	/* CU went 'not ready' */
			if (netif_running(dev))
				printk(KERN_ERR "%s: oops! CU has left active state. stat: %04x/%02x.\n",
					dev->name, stat, readb(&p->scb->cus));
		}
#endif

		if (debuglevel > 1)
			printk("%d", cnt++);

		/* Wait for ack. (ni52_xmt_int can be faster than ack!!) */
		wait_for_scb_cmd(dev);
		if (readb(&p->scb->cmd_cuc)) {	 /* timed out? */
			printk(KERN_ERR "%s: Acknowledge timed out.\n",
				dev->name);
			ni_disint();
			break;
		}
	}
	spin_unlock(&p->spinlock);

	if (debuglevel > 1)
		printk("i");
	return IRQ_HANDLED;
}
Exemple #2
0
static void ni52_rcv_int(struct net_device *dev)
{
	int status, cnt = 0;
	unsigned short totlen;
	struct sk_buff *skb;
	struct rbd_struct __iomem *rbd;
	struct priv *p = (struct priv *)dev->priv;

	if (debuglevel > 0)
		printk("R");

	for (; (status = readb(&p->rfd_top->stat_high)) & RFD_COMPL;) {
		rbd = make32(readw(&p->rfd_top->rbd_offset));
		if (status & RFD_OK) { /* frame received without error? */
			totlen = readw(&rbd->status);
			if (totlen & RBD_LAST) {
				/* the first and the last buffer? */
				totlen &= RBD_MASK; /* length of this frame */
				writew(0x00, &rbd->status);
				skb = (struct sk_buff *)dev_alloc_skb(totlen+2);
				if (skb != NULL) {
					skb_reserve(skb, 2);
					skb_put(skb, totlen);
					memcpy_fromio(skb->data, p->base + readl(&rbd->buffer), totlen);
					skb->protocol = eth_type_trans(skb, dev);
					netif_rx(skb);
					dev->last_rx = jiffies;
					p->stats.rx_packets++;
					p->stats.rx_bytes += totlen;
				} else
					p->stats.rx_dropped++;
			} else {
				int rstat;
				 /* free all RBD's until RBD_LAST is set */
				totlen = 0;
				while (!((rstat = readw(&rbd->status)) & RBD_LAST)) {
					totlen += rstat & RBD_MASK;
					if (!rstat) {
						printk(KERN_ERR "%s: Whoops .. no end mark in RBD list\n", dev->name);
						break;
					}
					writew(0, &rbd->status);
					rbd = make32(readw(&rbd->next));
				}
				totlen += rstat & RBD_MASK;
				writew(0, &rbd->status);
				printk(KERN_ERR "%s: received oversized frame! length: %d\n",
					dev->name, totlen);
				p->stats.rx_dropped++;
			 }
		} else {/* frame !(ok), only with 'save-bad-frames' */
			printk(KERN_ERR "%s: oops! rfd-error-status: %04x\n",
				dev->name, status);
			p->stats.rx_errors++;
		}
		writeb(0, &p->rfd_top->stat_high);
		writeb(RFD_SUSP, &p->rfd_top->last); /* maybe exchange by RFD_LAST */
		writew(0xffff, &p->rfd_top->rbd_offset);
		writeb(0, &p->rfd_last->last);	/* delete RFD_SUSP	*/
		p->rfd_last = p->rfd_top;
		p->rfd_top = make32(readw(&p->rfd_top->next)); /* step to next RFD */
		writew(make16(p->rfd_top), &p->scb->rfa_offset);

		if (debuglevel > 0)
			printk("%d", cnt++);
	}

	if (automatic_resume) {
		wait_for_scb_cmd(dev);
		writeb(RUC_RESUME, &p->scb->cmd_ruc);
		ni_attn586();
		wait_for_scb_cmd_ruc(dev);
	}

#ifdef WAIT_4_BUSY
	{
		int i;
		for (i = 0; i < 1024; i++) {
			if (p->rfd_top->status)
				break;
			udelay(16);
			if (i == 1023)
				printk(KERN_ERR "%s: RU hasn't fetched next RFD (not busy/complete)\n", dev->name);
		}
	}
#endif
	if (debuglevel > 0)
		printk("r");
}
Exemple #3
0
static int init586(struct net_device *dev)
{
	void __iomem *ptr;
	int i, result = 0;
	struct priv *p = (struct priv *)dev->priv;
	struct configure_cmd_struct __iomem *cfg_cmd;
	struct iasetup_cmd_struct __iomem *ias_cmd;
	struct tdr_cmd_struct __iomem *tdr_cmd;
	struct mcsetup_cmd_struct __iomem *mc_cmd;
	struct dev_mc_list *dmi = dev->mc_list;
	int num_addrs = dev->mc_count;

	ptr = p->scb + 1;

	cfg_cmd = ptr; /* configure-command */
	writew(0, &cfg_cmd->cmd_status);
	writew(CMD_CONFIGURE | CMD_LAST, &cfg_cmd->cmd_cmd);
	writew(0xFFFF, &cfg_cmd->cmd_link);

	/* number of cfg bytes */
	writeb(0x0a, &cfg_cmd->byte_cnt);
	/* fifo-limit (8=tx:32/rx:64) */
	writeb(fifo, &cfg_cmd->fifo);
	/* hold or discard bad recv frames (bit 7) */
	writeb(0x40, &cfg_cmd->sav_bf);
	/* addr_len |!src_insert |pre-len |loopback */
	writeb(0x2e, &cfg_cmd->adr_len);
	writeb(0x00, &cfg_cmd->priority);
	writeb(0x60, &cfg_cmd->ifs);;
	writeb(0x00, &cfg_cmd->time_low);
	writeb(0xf2, &cfg_cmd->time_high);
	writeb(0x00, &cfg_cmd->promisc);;
	if (dev->flags & IFF_ALLMULTI) {
		int len = ((char __iomem *)p->iscp - (char __iomem *)ptr - 8) / 6;
		if (num_addrs > len) {
			printk(KERN_ERR "%s: switching to promisc. mode\n",
				dev->name);
			dev->flags |= IFF_PROMISC;
		}
	}
	if (dev->flags & IFF_PROMISC)
		writeb(0x01, &cfg_cmd->promisc);
	writeb(0x00, &cfg_cmd->carr_coll);
	writew(make16(cfg_cmd), &p->scb->cbl_offset);
	writeb(0, &p->scb->cmd_ruc);

	writeb(CUC_START, &p->scb->cmd_cuc); /* cmd.-unit start */
	ni_attn586();

	wait_for_stat_compl(cfg_cmd);

	if ((readw(&cfg_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) !=
							(STAT_COMPL|STAT_OK)) {
		printk(KERN_ERR "%s: configure command failed: %x\n",
				dev->name, readw(&cfg_cmd->cmd_status));
		return 1;
	}

	/*
	 * individual address setup
	 */

	ias_cmd = ptr;

	writew(0, &ias_cmd->cmd_status);
	writew(CMD_IASETUP | CMD_LAST, &ias_cmd->cmd_cmd);
	writew(0xffff, &ias_cmd->cmd_link);

	memcpy_toio(&ias_cmd->iaddr, (char *)dev->dev_addr, ETH_ALEN);

	writew(make16(ias_cmd), &p->scb->cbl_offset);

	writeb(CUC_START, &p->scb->cmd_cuc); /* cmd.-unit start */
	ni_attn586();

	wait_for_stat_compl(ias_cmd);

	if ((readw(&ias_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) !=
							(STAT_OK|STAT_COMPL)) {
		printk(KERN_ERR "%s (ni52): individual address setup command failed: %04x\n", dev->name, readw(&ias_cmd->cmd_status));
		return 1;
	}

	/*
	 * TDR, wire check .. e.g. no resistor e.t.c
	 */

	tdr_cmd = ptr;

	writew(0, &tdr_cmd->cmd_status);
	writew(CMD_TDR | CMD_LAST, &tdr_cmd->cmd_cmd);
	writew(0xffff, &tdr_cmd->cmd_link);
	writew(0, &tdr_cmd->status);

	writew(make16(tdr_cmd), &p->scb->cbl_offset);
	writeb(CUC_START, &p->scb->cmd_cuc); /* cmd.-unit start */
	ni_attn586();

	wait_for_stat_compl(tdr_cmd);

	if (!(readw(&tdr_cmd->cmd_status) & STAT_COMPL))
		printk(KERN_ERR "%s: Problems while running the TDR.\n",
				dev->name);
	else {
		udelay(16);
		result = readw(&tdr_cmd->status);
		writeb(readb(&p->scb->cus) & STAT_MASK, &p->scb->cmd_cuc);
		ni_attn586(); /* ack the interrupts */

		if (result & TDR_LNK_OK)
			;
		else if (result & TDR_XCVR_PRB)
			printk(KERN_ERR "%s: TDR: Transceiver problem. Check the cable(s)!\n",
				dev->name);
		else if (result & TDR_ET_OPN)
			printk(KERN_ERR "%s: TDR: No correct termination %d clocks away.\n",
				dev->name, result & TDR_TIMEMASK);
		else if (result & TDR_ET_SRT) {
			/* time == 0 -> strange :-) */
			if (result & TDR_TIMEMASK)
				printk(KERN_ERR "%s: TDR: Detected a short circuit %d clocks away.\n",
					dev->name, result & TDR_TIMEMASK);
		} else
			printk(KERN_ERR "%s: TDR: Unknown status %04x\n",
						dev->name, result);
	}

	/*
	 * Multicast setup
	 */
	if (num_addrs && !(dev->flags & IFF_PROMISC)) {
		mc_cmd = ptr;
		writew(0, &mc_cmd->cmd_status);
		writew(CMD_MCSETUP | CMD_LAST, &mc_cmd->cmd_cmd);
		writew(0xffff, &mc_cmd->cmd_link);
		writew(num_addrs * 6, &mc_cmd->mc_cnt);

		for (i = 0; i < num_addrs; i++, dmi = dmi->next)
			memcpy_toio(mc_cmd->mc_list[i],
							dmi->dmi_addr, 6);

		writew(make16(mc_cmd), &p->scb->cbl_offset);
		writeb(CUC_START, &p->scb->cmd_cuc);
		ni_attn586();

		wait_for_stat_compl(mc_cmd);

		if ((readw(&mc_cmd->cmd_status) & (STAT_COMPL|STAT_OK))
						 != (STAT_COMPL|STAT_OK))
			printk(KERN_ERR "%s: Can't apply multicast-address-list.\n", dev->name);
	}

	/*
	 * alloc nop/xmit-cmds
	 */
#if (NUM_XMIT_BUFFS == 1)
	for (i = 0; i < 2; i++) {
		p->nop_cmds[i] = ptr;
		writew(CMD_NOP, &p->nop_cmds[i]->cmd_cmd);
		writew(0, &p->nop_cmds[i]->cmd_status);
		writew(make16(p->nop_cmds[i]), &p->nop_cmds[i]->cmd_link);
		ptr = ptr + sizeof(struct nop_cmd_struct);
	}
#else
	for (i = 0; i < NUM_XMIT_BUFFS; i++) {
		p->nop_cmds[i] = ptr;
		writew(CMD_NOP, &p->nop_cmds[i]->cmd_cmd);
		writew(0, &p->nop_cmds[i]->cmd_status);
		writew(make16(p->nop_cmds[i]), &p->nop_cmds[i]->cmd_link);
		ptr = ptr + sizeof(struct nop_cmd_struct);
	}
#endif

	ptr = alloc_rfa(dev, ptr); /* init receive-frame-area */

	/*
	 * alloc xmit-buffs / init xmit_cmds
	 */
	for (i = 0; i < NUM_XMIT_BUFFS; i++) {
		/* Transmit cmd/buff 0 */
		p->xmit_cmds[i] = ptr;
		ptr = ptr + sizeof(struct transmit_cmd_struct);
		p->xmit_cbuffs[i] = ptr; /* char-buffs */
		ptr = ptr + XMIT_BUFF_SIZE;
		p->xmit_buffs[i] = ptr; /* TBD */
		ptr = ptr + sizeof(struct tbd_struct);
		if ((void __iomem *)ptr > (void __iomem *)p->iscp) {
			printk(KERN_ERR "%s: not enough shared-mem for your configuration!\n",
				dev->name);
			return 1;
		}
		memset_io(p->xmit_cmds[i], 0,
					sizeof(struct transmit_cmd_struct));
		memset_io(p->xmit_buffs[i], 0,
					sizeof(struct tbd_struct));
		writew(make16(p->nop_cmds[(i+1)%NUM_XMIT_BUFFS]),
					&p->xmit_cmds[i]->cmd_link);
		writew(STAT_COMPL, &p->xmit_cmds[i]->cmd_status);
		writew(CMD_XMIT|CMD_INT, &p->xmit_cmds[i]->cmd_cmd);
		writew(make16(p->xmit_buffs[i]), &p->xmit_cmds[i]->tbd_offset);
		writew(0xffff, &p->xmit_buffs[i]->next);
		writel(make24(p->xmit_cbuffs[i]), &p->xmit_buffs[i]->buffer);
	}

	p->xmit_count = 0;
	p->xmit_last	= 0;
#ifndef NO_NOPCOMMANDS
	p->nop_point	= 0;
#endif

	 /*
		* 'start transmitter'
		*/
#ifndef NO_NOPCOMMANDS
	writew(make16(p->nop_cmds[0]), &p->scb->cbl_offset);
	writeb(CUC_START, &p->scb->cmd_cuc);
	ni_attn586();
	wait_for_scb_cmd(dev);
#else
	writew(make16(p->xmit_cmds[0]), &p->xmit_cmds[0]->cmd_link);
	writew(CMD_XMIT | CMD_SUSPEND | CMD_INT, &p->xmit_cmds[0]->cmd_cmd);
#endif

	/*
	 * ack. interrupts
	 */
	writeb(readb(&p->scb->cus) & STAT_MASK, &p->scb->cmd_cuc);
	ni_attn586();
	udelay(16);

	ni_enaint();

	return 0;
}
Exemple #4
0
static int ni52_send_packet(struct sk_buff *skb, struct net_device *dev)
{
	int len, i;
#ifndef NO_NOPCOMMANDS
	int next_nop;
#endif
	struct priv *p = (struct priv *) dev->priv;

	if (skb->len > XMIT_BUFF_SIZE) {
		printk(KERN_ERR "%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n", dev->name, XMIT_BUFF_SIZE, skb->len);
		return 0;
	}

	netif_stop_queue(dev);

	memcpy_toio(p->xmit_cbuffs[p->xmit_count], skb->data, skb->len);
	len = skb->len;
	if (len < ETH_ZLEN) {
		len = ETH_ZLEN;
		memset_io(p->xmit_cbuffs[p->xmit_count]+skb->len, 0,
							len - skb->len);
	}

#if (NUM_XMIT_BUFFS == 1)
#	ifdef NO_NOPCOMMANDS

#ifdef DEBUG
	if (readb(&p->scb->cus) & CU_ACTIVE) {
		printk(KERN_ERR "%s: Hmmm .. CU is still running and we wanna send a new packet.\n", dev->name);
		printk(KERN_ERR "%s: stat: %04x %04x\n",
				dev->name, readb(&p->scb->cus),
				readw(&p->xmit_cmds[0]->cmd_status));
	}
#endif
	writew(TBD_LAST | len, &p->xmit_buffs[0]->size);
	for (i = 0; i < 16; i++) {
		writew(0, &p->xmit_cmds[0]->cmd_status);
		wait_for_scb_cmd(dev);
		if ((readb(&p->scb->cus) & CU_STATUS) == CU_SUSPEND)
			writeb(CUC_RESUME, &p->scb->cmd_cuc);
		else {
			writew(make16(p->xmit_cmds[0]), &p->scb->cbl_offset);
			writeb(CUC_START, &p->scb->cmd_cuc);
		}
		ni_attn586();
		dev->trans_start = jiffies;
		if (!i)
			dev_kfree_skb(skb);
		wait_for_scb_cmd(dev);
		/* test it, because CU sometimes doesn't start immediately */
		if (readb(&p->scb->cus) & CU_ACTIVE)
			break;
		if (readw(&p->xmit_cmds[0]->cmd_status))
			break;
		if (i == 15)
			printk(KERN_WARNING "%s: Can't start transmit-command.\n", dev->name);
	}
#	else
	next_nop = (p->nop_point + 1) & 0x1;
	writew(TBD_LAST | len, &p->xmit_buffs[0]->size);
	writew(make16(p->nop_cmds[next_nop]), &p->xmit_cmds[0]->cmd_link);
	writew(make16(p->nop_cmds[next_nop]),
				&p->nop_cmds[next_nop]->cmd_link);
	writew(0, &p->xmit_cmds[0]->cmd_status);
	writew(0, &p->nop_cmds[next_nop]->cmd_status);

	writew(make16(p->xmit_cmds[0]), &p->nop_cmds[p->nop_point]->cmd_link);
	dev->trans_start = jiffies;
	p->nop_point = next_nop;
	dev_kfree_skb(skb);
#	endif
#else
	writew(TBD_LAST | len, &p->xmit_buffs[p->xmit_count]->size);
	next_nop = p->xmit_count + 1
	if (next_nop == NUM_XMIT_BUFFS)
		next_nop = 0;
	writew(0, &p->xmit_cmds[p->xmit_count]->cmd_status);
	/* linkpointer of xmit-command already points to next nop cmd */
	writew(make16(p->nop_cmds[next_nop]),
				&p->nop_cmds[next_nop]->cmd_link);
	writew(0, &p->nop_cmds[next_nop]->cmd_status);
	writew(make16(p->xmit_cmds[p->xmit_count]),
				&p->nop_cmds[p->xmit_count]->cmd_link);
	dev->trans_start = jiffies;
	p->xmit_count = next_nop;
	{
		unsigned long flags;
		spin_lock_irqsave(&p->spinlock);
		if (p->xmit_count != p->xmit_last)
			netif_wake_queue(dev);
		spin_unlock_irqrestore(&p->spinlock);
	}
	dev_kfree_skb(skb);
#endif
	return 0;
}
Exemple #5
0
static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
			  u_int transp, struct fb_info *info)
{
	struct offb_par *par = (struct offb_par *) info->par;
	int i, depth;
	u32 *pal = info->pseudo_palette;

	depth = info->var.bits_per_pixel;
	if (depth == 16)
		depth = (info->var.green.length == 5) ? 15 : 16;

	if (regno > 255 ||
	    (depth == 16 && regno > 63) ||
	    (depth == 15 && regno > 31))
		return 1;

	if (regno < 16) {
		switch (depth) {
		case 15:
			pal[regno] = (regno << 10) | (regno << 5) | regno;
			break;
		case 16:
			pal[regno] = (regno << 11) | (regno << 5) | regno;
			break;
		case 24:
			pal[regno] = (regno << 16) | (regno << 8) | regno;
			break;
		case 32:
			i = (regno << 8) | regno;
			pal[regno] = (i << 16) | i;
			break;
		}
	}

	red >>= 8;
	green >>= 8;
	blue >>= 8;

	if (!par->cmap_adr)
		return 0;

	switch (par->cmap_type) {
	case cmap_m64:
		writeb(regno, par->cmap_adr);
		writeb(red, par->cmap_data);
		writeb(green, par->cmap_data);
		writeb(blue, par->cmap_data);
		break;
	case cmap_M3A:
		/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
		out_le32(par->cmap_adr + 0x58,
			 in_le32(par->cmap_adr + 0x58) & ~0x20);
	case cmap_r128:
		/* Set palette index & data */
		out_8(par->cmap_adr + 0xb0, regno);
		out_le32(par->cmap_adr + 0xb4,
			 (red << 16 | green << 8 | blue));
		break;
	case cmap_M3B:
		/* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
		out_le32(par->cmap_adr + 0x58,
			 in_le32(par->cmap_adr + 0x58) | 0x20);
		/* Set palette index & data */
		out_8(par->cmap_adr + 0xb0, regno);
		out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue));
		break;
	case cmap_radeon:
		/* Set palette index & data (could be smarter) */
		out_8(par->cmap_adr + 0xb0, regno);
		out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue));
		break;
	case cmap_gxt2000:
		out_le32(((unsigned __iomem *) par->cmap_adr) + regno,
			 (red << 16 | green << 8 | blue));
		break;
	case cmap_avivo:
		/* Write to both LUTs for now */
		writel(1, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
		writeb(regno, par->cmap_adr + AVIVO_DC_LUT_RW_INDEX);
		writel(((red) << 22) | ((green) << 12) | ((blue) << 2),
		       par->cmap_adr + AVIVO_DC_LUT_30_COLOR);
		writel(0, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
		writeb(regno, par->cmap_adr + AVIVO_DC_LUT_RW_INDEX);
		writel(((red) << 22) | ((green) << 12) | ((blue) << 2),
		       par->cmap_adr + AVIVO_DC_LUT_30_COLOR);
		break;
	}

	return 0;
}
Exemple #6
0
static inline void write_sc_port(struct uart_port *p, u8 reg, u8 val)
{
	writeb(val, p->membase + p->line * 0x20 + reg);
}
void RIOFixPhbs(struct rio_info *p, struct Host *HostP, unsigned int unit)
{
	unsigned short link, port;
	struct Port *PortP;
	unsigned long flags;
	int PortN = HostP->Mapping[unit].SysPort;

	rio_dprintk(RIO_DEBUG_ROUTE, "RIOFixPhbs unit %d sysport %d\n", unit, PortN);

	if (PortN != -1) {
		unsigned short dest_unit = HostP->Mapping[unit].ID2;

		/*
		 ** Get the link number used for the 1st 8 phbs on this unit.
		 */
		PortP = p->RIOPortp[HostP->Mapping[dest_unit - 1].SysPort];

		link = readw(&PortP->PhbP->link);

		for (port = 0; port < PORTS_PER_RTA; port++, PortN++) {
			unsigned short dest_port = port + 8;
			u16 __iomem *TxPktP;
			struct PKT __iomem *Pkt;

			PortP = p->RIOPortp[PortN];

			rio_spin_lock_irqsave(&PortP->portSem, flags);
			/*
			 ** If RTA is not powered on, the tx packets will be
			 ** unset, so go no further.
			 */
			if (!PortP->TxStart) {
				rio_dprintk(RIO_DEBUG_ROUTE, "Tx pkts not set up yet\n");
				rio_spin_unlock_irqrestore(&PortP->portSem, flags);
				break;
			}

			/*
			 ** For the second slot of a 16 port RTA, the driver needs to
			 ** sort out the phb to port mappings. The dest_unit for this
			 ** group of 8 phbs is set to the dest_unit of the accompanying
			 ** 8 port block. The dest_port of the second unit is set to
			 ** be in the range 8-15 (i.e. 8 is added). Thus, for a 16 port
			 ** RTA with IDs 5 and 6, traffic bound for port 6 of unit 6
			 ** (being the second map ID) will be sent to dest_unit 5, port
			 ** 14. When this RTA is deleted, dest_unit for ID 6 will be
			 ** restored, and the dest_port will be reduced by 8.
			 ** Transmit packets also have a destination field which needs
			 ** adjusting in the same manner.
			 ** Note that the unit/port bytes in 'dest' are swapped.
			 ** We also need to adjust the phb and rup link numbers for the
			 ** second block of 8 ttys.
			 */
			for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) {
				/*
				 ** *TxPktP is the pointer to the transmit packet on the host
				 ** card. This needs to be translated into a 32 bit pointer
				 ** so it can be accessed from the driver.
				 */
				Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(TxPktP));

				/*
				 ** If the packet is used, reset it.
				 */
				Pkt = (struct PKT __iomem *) ((unsigned long) Pkt & ~PKT_IN_USE);
				writeb(dest_unit, &Pkt->dest_unit);
				writeb(dest_port, &Pkt->dest_port);
			}
			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);
			writew(dest_unit + (dest_port << 8), &PortP->PhbP->destination);
			writew(link, &PortP->PhbP->link);

			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
		}
		/*
		 ** Now make sure the range of ports to be serviced includes
		 ** the 2nd 8 on this 16 port RTA.
		 */
		if (link > 3)
			return;
		if (((unit * 8) + 7) > readw(&HostP->LinkStrP[link].last_port)) {
			rio_dprintk(RIO_DEBUG_ROUTE, "last port on host link %d: %d\n", link, (unit * 8) + 7);
			writew((unit * 8) + 7, &HostP->LinkStrP[link].last_port);
		}
	}