Re: [PATCH] Make sgiseeq.c 64bit ready (was: CVS Update@xxxxxxxxxxx: linux)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Thiemo Seufer wrote:
> Thiemo Seufer wrote:
> [snip]
> > This patch makes (as the original) the assumption that
> > sizeof(void *) == 4, so it will work for 32bit only.
> > 
> > My seemingly working code for mips64 is appeded as patch against
> > current CVS.
> 
> And since I've overlooked the changed vaddr type it didn't work
> any more. The updated patch below reverts this and adds proper
> alignment to the DMA descriptor definition in mips64.
> 
> Note1: CONFIG_SGI_IP28 reads as "has real 64bit address space",
>        it's currently defined nowhere in CVS tree.
> 
> Note2: SGI_KEYBOARD_IRQ in sgihpc.h is never used anywhere.

And I'm an idiot and sent an old patch as update. Next try...


Thiemo


diff -BurPX /bigdisk/dl/src/dontdiff linux-orig/drivers/net/sgiseeq.c linux/drivers/net/sgiseeq.c
--- linux-orig/drivers/net/sgiseeq.c	Sun Jun 24 19:55:01 2001
+++ linux/drivers/net/sgiseeq.c	Thu Jun 28 13:56:24 2001
@@ -1,5 +1,4 @@
-/* $Id: sgiseeq.c,v 1.17 2000/03/27 23:02:57 ralf Exp $
- *
+/*
  * sgiseeq.c: Seeq8003 ethernet driver for SGI machines.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -67,31 +66,36 @@
 			    sp->tx_old + (SEEQ_TX_BUFFERS - 1) - sp->tx_new : \
 			    sp->tx_old - sp->tx_new - 1)
 
-#define DEBUG
+/* #define DEBUG */
 
 struct sgiseeq_rx_desc {
 	struct hpc_dma_desc rdma;
-	signed int buf_vaddr;
+	signed long buf_vaddr;
 };
 
 struct sgiseeq_tx_desc {
 	struct hpc_dma_desc tdma;
-	signed int buf_vaddr;
+	signed long buf_vaddr;
 };
 
-/* Warning: This structure is layed out in a certain way because
- *          HPC dma descriptors must be 8-byte aligned.  So don't
- *          touch this without some care.
+/* Warning: This structure is layed out in a certain way because HPC dma
+ *          descriptors must be 8-byte aligned.  So don't touch this without
+ *          some care.
+ *          The spec states 16-byte alignment is needed, so I changed the
+ *          padding and aligned the whole struct accordingly. --THS
  */
 struct sgiseeq_init_block { /* Note the name ;-) */
-	/* Ptrs to the descriptors in KSEG1 uncached space. */
+	/* Ptrs to the descriptors in KSEG1 or XKPHYS uncached space. */
 	struct sgiseeq_rx_desc *rx_desc;
 	struct sgiseeq_tx_desc *tx_desc;
-	unsigned int _padding[30]; /* Pad out to largest cache line size. */
+	/* Pad out to largest cache line size (64 byte with 32bit, 128 byte
+	 * with 64bit pointers).
+	 */
+	char _padding[14 * sizeof(void *)];
 
 	struct sgiseeq_rx_desc rxvector[SEEQ_RX_BUFFERS];
 	struct sgiseeq_tx_desc txvector[SEEQ_TX_BUFFERS];
-};
+} __attribute__((aligned(16)));
 
 struct sgiseeq_private {
 	volatile struct sgiseeq_init_block srings;
@@ -149,6 +153,12 @@
 #define RCNTCFG_INIT  (HPCDMA_OWN | HPCDMA_EORP | HPCDMA_XIE)
 #define RCNTINFO_INIT (RCNTCFG_INIT | (PKT_BUF_SZ & HPCDMA_BCNT))
 
+#ifdef CONFIG_SGI_IP28
+#define THIS_K1ADDR K1ADDR
+#else
+#define THIS_K1ADDR KSEG1ADDR
+#endif
+
 static int seeq_init_ring(struct net_device *dev)
 {
 	struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv;
@@ -172,12 +182,12 @@
 		if(!ib->tx_desc[i].tdma.pbuf) {
 			unsigned long buffer;
 
-			buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL);
+			buffer = (unsigned long)kmalloc(PKT_BUF_SZ,
+							GFP_KERNEL | GFP_DMA);
 			if (!buffer)
 				return -ENOMEM;
-			ib->tx_desc[i].buf_vaddr = KSEG1ADDR(buffer);
+			ib->tx_desc[i].buf_vaddr = THIS_K1ADDR(buffer);
 			ib->tx_desc[i].tdma.pbuf = PHYSADDR(buffer);
-//			flush_cache_all();
 		}
 		ib->tx_desc[i].tdma.cntinfo = (TCNTINFO_INIT);
 	}
@@ -187,12 +197,12 @@
 		if (!ib->rx_desc[i].rdma.pbuf) {
 			unsigned long buffer;
 
-			buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL);
+			buffer = (unsigned long)kmalloc(PKT_BUF_SZ,
+							GFP_KERNEL | GFP_DMA);
 			if (!buffer)
 				return -ENOMEM;
-			ib->rx_desc[i].buf_vaddr = KSEG1ADDR(buffer);
+			ib->rx_desc[i].buf_vaddr = THIS_K1ADDR(buffer);
 			ib->rx_desc[i].rdma.pbuf = PHYSADDR(buffer);
-//			flush_cache_all();
 		}
 		ib->rx_desc[i].rdma.cntinfo = (RCNTINFO_INIT);
 	}
@@ -300,10 +310,6 @@
 	}
 }
 
-#define for_each_rx(rd, sp) for((rd) = &(sp)->srings.rx_desc[(sp)->rx_new]; \
-				!((rd)->rdma.cntinfo & HPCDMA_OWN); \
-				(rd) = &(sp)->srings.rx_desc[(sp)->rx_new])
-
 static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp,
 			      volatile struct hpc3_ethregs *hregs,
 			      volatile struct sgiseeq_regs *sregs)
@@ -316,7 +322,9 @@
 	unsigned int orig_end = PREV_RX(sp->rx_new);
 
 	/* Service every received packet. */
-	for_each_rx(rd, sp) {
+	for(rd = &sp->srings.rx_desc[sp->rx_new];
+	    !(rd->rdma.cntinfo & HPCDMA_OWN);
+	    rd = &sp->srings.rx_desc[sp->rx_new]) {
 		len = (PKT_BUF_SZ - (rd->rdma.cntinfo & HPCDMA_BCNT) - 3);
 		pkt_pointer = (unsigned char *)(long)rd->buf_vaddr;
 		pkt_status = pkt_pointer[len + 2];
@@ -338,7 +346,7 @@
 				sp->stats.rx_packets++;
 				sp->stats.rx_bytes += len;
 			} else {
-				printk ("%s: Memory squeeze, deferring packet.\n",
+				printk("%s: Memory squeeze, deferring packet.\n",
 					dev->name);
 				sp->stats.rx_dropped++;
 			}
@@ -370,12 +378,12 @@
 	/* If the HPC aint doin nothin, and there are more packets
 	 * with ETXD cleared and XIU set we must make very certain
 	 * that we restart the HPC else we risk locking up the
-	 * adapter.  The following code is only safe iff the HPCDMA
+	 * adapter.  The following code is only safe if the HPCDMA
 	 * is not active!
 	 */
 	while ((td->tdma.cntinfo & (HPCDMA_XIU | HPCDMA_ETXD)) ==
 	      (HPCDMA_XIU | HPCDMA_ETXD))
-		td = (struct sgiseeq_tx_desc *)(long) KSEG1ADDR(td->tdma.pnext);
+		td = (struct sgiseeq_tx_desc *)THIS_K1ADDR(td->tdma.pnext);
 	if (td->tdma.cntinfo & HPCDMA_XIU) {
 		hregs->tx_ndptr = PHYSADDR(td);
 		hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE;
@@ -435,7 +443,7 @@
 	/* Always check for received packets. */
 	sgiseeq_rx(dev, sp, hregs, sregs);
 
-	/* Only check for tx acks iff we have something queued. */
+	/* Only check for tx acks if we have something queued. */
 	if (sp->tx_old != sp->tx_new)
 		sgiseeq_tx(dev, sp, hregs, sregs);
 
@@ -497,11 +505,13 @@
 	return 0;
 }
 
+#ifdef DEBUG
 void sgiseeq_my_reset(void)
 {
 	printk("RESET!\n");
 	sgiseeq_reset(gdev);
 }
+#endif
 
 static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
@@ -528,7 +538,7 @@
 	 *    we have completely set up it's state.  This means, do
 	 *    not clear HPCDMA_EOX in the current last descritptor
 	 *    until the one we are adding looks consistant and could
-	 *    be processes right now.
+	 *    be processed right now.
 	 * 3) The tx interrupt code must notice when we've added a new
 	 *    entry and the HPC got to the end of the chain before we
 	 *    added this new entry and restarted it.
@@ -584,7 +594,6 @@
 
 	while (i < (nbufs - 1)) {
 		buf[i].tdma.pnext = PHYSADDR(&buf[i + 1]);
-		buf[i].tdma.pbuf = 0;
 		i++;
 	}
 	buf[i].tdma.pnext = PHYSADDR(&buf[0]);
@@ -596,25 +605,22 @@
 
 	while (i < (nbufs - 1)) {
 		buf[i].rdma.pnext = PHYSADDR(&buf[i + 1]);
-		buf[i].rdma.pbuf = 0;
 		i++;
 	}
-	buf[i].rdma.pbuf = 0;
 	buf[i].rdma.pnext = PHYSADDR(&buf[0]);
 }
 
 static char onboard_eth_addr[6];
 
-#define ALIGNED(x)  ((((unsigned long)(x)) + 0xf) & ~(0xf))
-
-int sgiseeq_init(struct net_device *dev, struct sgiseeq_regs *sregs,
-		 struct hpc3_ethregs *hregs, int irq)
+static int sgiseeq_init(struct net_device *dev, struct sgiseeq_regs *sregs,
+			struct hpc3_ethregs *hregs, int irq)
 {
 	static unsigned version_printed;
 	int i;
 	struct sgiseeq_private *sp;
 
-	dev->priv = (struct sgiseeq_private *) get_free_page(GFP_KERNEL);
+	dev->priv = (struct sgiseeq_private *)
+		    get_zeroed_page(GFP_KERNEL | GFP_DMA);
 	if (dev->priv == NULL)
 		return -ENOMEM;
 
@@ -635,17 +641,16 @@
 	gpriv = sp;
 	gdev = dev;
 #endif
-	memset((char *)dev->priv, 0, sizeof(struct sgiseeq_private));
 	sp->sregs = sregs;
 	sp->hregs = hregs;
 	sp->name = sgiseeqstr;
 
 	sp->srings.rx_desc = (struct sgiseeq_rx_desc *)
-	                     (KSEG1ADDR(ALIGNED(&sp->srings.rxvector[0])));
+	                     (THIS_K1ADDR(&sp->srings.rxvector[0]));
 	dma_cache_wback_inv((unsigned long)&sp->srings.rxvector,
 	                    sizeof(sp->srings.rxvector));
 	sp->srings.tx_desc = (struct sgiseeq_tx_desc *)
-	                     (KSEG1ADDR(ALIGNED(&sp->srings.txvector[0])));
+	                     (THIS_K1ADDR(&sp->srings.txvector[0]));
 	dma_cache_wback_inv((unsigned long)&sp->srings.txvector,
 	                    sizeof(sp->srings.txvector));
 
@@ -677,6 +682,8 @@
 	return 0;
 }
 
+#undef THIS_K1ADDR
+
 static inline unsigned char str2hexnum(unsigned char c)
 {
 	if (c >= '0' && c <= '9')
@@ -712,7 +719,6 @@
 
 	/* First get the ethernet address of the onboard interface from ARCS.
 	 * This is fragile; PROM doesn't like running from cache.
-	 * On MIPS64 it crashes for some other, yet unknown reason ...
 	 */
 	ep = ArcGetEnvironmentVariable("eaddr");
 	str2eaddr(onboard_eth_addr, ep);
diff -BurPX /bigdisk/dl/src/dontdiff linux-orig/include/asm-mips64/addrspace.h linux/include/asm-mips64/addrspace.h
--- linux-orig/include/asm-mips64/addrspace.h	Thu Oct 26 03:18:01 2000
+++ linux/include/asm-mips64/addrspace.h	Thu Jun 28 13:56:24 2001
@@ -1,5 +1,4 @@
-/* $Id: addrspace.h,v 1.5 2000/02/01 00:32:01 kanoj Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -104,9 +103,13 @@
 #endif
 #define K2BASE		0xc000000000000000
 
+#define K0ADDR(x)	(PHYSADDR(x) | K0BASE)
+#define K1ADDR(x)	(PHYSADDR(x) | K1BASE)
+#define K2ADDR(x)	(PHYSADDR(x) | K2BASE)
+
 #if !defined (CONFIG_CPU_R8000)
-#define COMPAT_K1BASE32		0xffffffffa0000000
-#define PHYS_TO_COMPATK1(x)	((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */
+#define COMPAT_K1BASE32		0xffffffffa0000000  /* 32-bit compat k1 */
+#define PHYS_TO_COMPATK1(x)	((unsigned long)(x) | COMPAT_K1BASE32)
 #endif
 
 #define KDM_TO_PHYS(x)	((unsigned long)(x) & TO_PHYS_MASK)
diff -BurPX /bigdisk/dl/src/dontdiff linux-orig/include/asm-mips64/sgi/sgihpc.h linux/include/asm-mips64/sgi/sgihpc.h
--- linux-orig/include/asm-mips64/sgi/sgihpc.h	Sat Dec  4 04:59:13 1999
+++ linux/include/asm-mips64/sgi/sgihpc.h	Thu Jun 28 14:04:18 2001
@@ -1,5 +1,4 @@
-/* $Id: sgihpc.h,v 1.2 1999/10/19 20:51:54 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -36,7 +35,8 @@
 #define HPCDMA_BCNT   0x00003fff /* size in bytes of this dma buffer */
 
 	int pnext;		 /* paddr of next hpc_dma_desc if any */
-};
+	int _padding;		 /* pad to quad word size */
+} __attribute__((aligned(16)));
 
 typedef volatile unsigned int hpcreg;
 
@@ -333,8 +333,6 @@
 
 /* We need software copies of these because they are write only. */
 extern unsigned int sgi_hpc_write1, sgi_hpc_write2;
-
-#define SGI_KEYBOARD_IRQ 20
 
 struct hpc_keyb {
 #ifdef __MIPSEB__


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux