2.5.50-BK patches

Anton Blanchard anton at samba.org
Tue Dec 10 01:53:28 EST 2002


Hi,

Here are the patches I am currently running with 2.5.50-BK. On the
weekend I merged Todd's EEH work from 2.4 and began work on getting
the PCI layer in shape.

With the attached patches pSeries LPAR works again. Instead of
faking up function 0 for multifunction devices where we only own
non 0 functions I made a few line change to the pci probe code so
we always probe all functions. The old code was fragile and in fact
broken in 2.5.

The e100 and e1000 need some care and attention, Im part way through
fixing bugs in these drivers. At least with the patches they work
reasonably well.

Anton
-------------- next part --------------
===== Makefile 1.321 vs edited =====
--- 1.321/Makefile	Wed Oct 16 13:29:35 2002
+++ edited/Makefile	Wed Oct 16 15:02:15 2002
@@ -46,7 +46,7 @@
 HOSTCC  	= gcc
 HOSTCFLAGS	= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer

-CROSS_COMPILE 	=
+CROSS_COMPILE 	= /usr/local/ppc64/bin/powerpc64-linux-

 # 	That's our default target when none is given on the command line

===== include/linux/pci.h 1.47 vs edited =====
--- 1.47/include/linux/pci.h	Tue Oct  8 00:43:44 2002
+++ edited/include/linux/pci.h	Wed Oct  9 10:54:24 2002
@@ -420,10 +420,10 @@
 	void		*sysdata;	/* hook for sys-specific extension */
 	struct proc_dir_entry *procdir;	/* directory entry in /proc/bus/pci */

-	unsigned char	number;		/* bus number */
-	unsigned char	primary;	/* number of primary bridge */
-	unsigned char	secondary;	/* number of secondary bridge */
-	unsigned char	subordinate;	/* max number of subordinate buses */
+	unsigned int	number;		/* bus number */
+	unsigned int	primary;	/* number of primary bridge */
+	unsigned int	secondary;	/* number of secondary bridge */
+	unsigned int	subordinate;	/* max number of subordinate buses */

 	char		name[48];
 	unsigned short	vendor;
===== arch/ppc64/kernel/process.c 1.24 vs edited =====
--- 1.24/arch/ppc64/kernel/process.c	Sun Dec  8 15:45:11 2002
+++ edited/arch/ppc64/kernel/process.c	Sun Dec  8 15:47:55 2002
@@ -69,6 +69,9 @@
 int
 dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
 {
+	/* Anton: fix threaded coredumps!!! */
+	if (!regs)
+		return 1;
 	if (regs->msr & MSR_FP)
 		giveup_fpu(current);
 	memcpy(fpregs, &current->thread.fpr[0], sizeof(*fpregs));
-------------- next part --------------
===== drivers/net/e1000/e1000_main.c 1.40 vs edited =====
--- 1.40/drivers/net/e1000/e1000_main.c	Sat Oct 19 08:05:05 2002
+++ edited/drivers/net/e1000/e1000_main.c	Tue Oct 29 09:46:32 2002
@@ -437,7 +437,7 @@
 		netdev->features = NETIF_F_SG;
 	}

-#ifdef NETIF_F_TSO
+#ifdef NETIF_F_TSO_NO
 	if(adapter->hw.mac_type >= e1000_82544)
 		netdev->features |= NETIF_F_TSO;
 #endif
@@ -1313,7 +1313,7 @@
 static inline boolean_t
 e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb, int tx_flags)
 {
-#ifdef NETIF_F_TSO
+#ifdef NETIF_F_TSO_NO
 	struct e1000_context_desc *context_desc;
 	int i;
 	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
@@ -1515,7 +1515,7 @@
 	for(f = 0; f < skb_shinfo(skb)->nr_frags; f++)
 		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
 		                       adapter->max_data_per_txd);
-#ifdef NETIF_F_TSO
+#ifdef NETIF_F_TSO_NO
 	if((skb_shinfo(skb)->tso_size) || (skb->ip_summed == CHECKSUM_HW))
 		count++;
 #else

-------------- next part --------------
===== drivers/net/e100/e100.h 1.19 vs edited =====
--- 1.19/drivers/net/e100/e100.h	Wed Nov  6 03:31:33 2002
+++ edited/drivers/net/e100/e100.h	Mon Dec  9 15:51:25 2002
@@ -705,8 +705,6 @@
 #define IPCB_HARDWAREPARSING_ENABLE	BIT_0
 #define IPCB_INSERTVLAN_ENABLE 		BIT_1
 #define IPCB_IP_ACTIVATION_DEFAULT      IPCB_HARDWAREPARSING_ENABLE
-
-#define FOLD_CSUM(_XSUM)  ((((_XSUM << 16) | (_XSUM >> 16)) + _XSUM) >> 16)

 /* Transmit Buffer Descriptor (TBD)*/
 typedef struct _tbd_t {
===== drivers/net/e100/e100_main.c 1.30 vs edited =====
--- 1.30/drivers/net/e100/e100_main.c	Sat Nov 30 03:18:46 2002
+++ edited/drivers/net/e100/e100_main.c	Sun Dec  8 20:54:06 2002
@@ -1417,7 +1417,7 @@
 		pcurr_tcb->tcb_skb = NULL;
 	}

-	wmb();
+	mb();
 }

 /***************************************************************************/
@@ -1675,7 +1675,7 @@
 		e100_dump_stats_cntrs(bdp);
 	}

-	wmb();
+	mb();

 	/* relaunch watchdog timer in 2 sec */
 	mod_timer(&(bdp->watchdog_timer), jiffies + (2 * HZ));
@@ -1774,15 +1774,11 @@
 		return;
 	}

-	/* disable intr before we ack & after identifying the intr as ours */
-	e100_dis_intr(bdp);
-
 	writew(intr_status, &bdp->scb->scb_status);	/* ack intrs */
 	readw(&bdp->scb->scb_status);

 	/* the device is closed, don't continue or else bad things may happen. */
 	if (!netif_running(dev)) {
-		e100_set_intr_mask(bdp);
 		return;
 	}

@@ -1801,8 +1797,6 @@
 		bdp->tx_count = 0;	/* restart tx interrupt batch count */
 		e100_tx_srv(bdp);
 	}
-
-	e100_set_intr_mask(bdp);
 }

 /**
@@ -2053,32 +2047,6 @@
 }

 /**
- * e100_pseudo_hdr_csum - compute IP pseudo-header checksum
- * @ip: points to the header of the IP packet
- *
- * Return the 16 bit checksum of the IP pseudo-header.,which is computed
- * on the fields: IP src, IP dst, next protocol, payload length.
- * The checksum vaule is returned in network byte order.
- */
-static inline u16
-e100_pseudo_hdr_csum(const struct iphdr *ip)
-{
-	u32 pseudo = 0;
-	u32 payload_len = 0;
-
-	payload_len = ntohs(ip->tot_len) - (ip->ihl * 4);
-
-	pseudo += htons(payload_len);
-	pseudo += (ip->protocol << 8);
-	pseudo += ip->saddr & 0x0000ffff;
-	pseudo += (ip->saddr & 0xffff0000) >> 16;
-	pseudo += ip->daddr & 0x0000ffff;
-	pseudo += (ip->daddr & 0xffff0000) >> 16;
-
-	return FOLD_CSUM(pseudo);
-}
-
-/**
  * e100_prepare_xmit_buff - prepare a buffer for transmission
  * @bdp: atapter's private data struct
  * @skb: skb to send
@@ -2121,27 +2089,13 @@

 		if ((ip->protocol == IPPROTO_TCP) ||
 		    (ip->protocol == IPPROTO_UDP)) {
-			u16 *chksum;
-
 			tcb->tcbu.ipcb.ip_activation_high =
 				IPCB_HARDWAREPARSING_ENABLE;
 			tcb->tcbu.ipcb.ip_schedule |=
 				IPCB_TCPUDP_CHECKSUM_ENABLE;

-			if (ip->protocol == IPPROTO_TCP) {
-				struct tcphdr *tcp;
-
-				tcp = (struct tcphdr *) ((u32 *) ip + ip->ihl);
-				chksum = &(tcp->check);
+			if (ip->protocol == IPPROTO_TCP)
 				tcb->tcbu.ipcb.ip_schedule |= IPCB_TCP_PACKET;
-			} else {
-				struct udphdr *udp;
-
-				udp = (struct udphdr *) ((u32 *) ip + ip->ihl);
-				chksum = &(udp->check);
-			}
-
-			*chksum = e100_pseudo_hdr_csum(ip);
 		}
 	}

@@ -2188,7 +2142,7 @@

 	bdp->tcb_pool.tail = NEXT_TCB_TOUSE(bdp->tcb_pool.tail);

-	wmb();
+	mb();

 	e100_start_cu(bdp, tcb);

@@ -2211,9 +2165,7 @@
 void
 e100_start_cu(struct e100_private *bdp, tcb_t *tcb)
 {
-	unsigned long lock_flag;
-
-	spin_lock_irqsave(&(bdp->bd_lock), lock_flag);
+	spin_lock(&(bdp->bd_lock));
 	switch (bdp->next_cu_cmd) {
 	case RESUME_NO_WAIT:
 		/*last cu command was a CU_RESMUE if this is a 558 or newer we dont need to
@@ -2258,7 +2210,7 @@
 	/* save the last tcb */
 	bdp->last_tcb = tcb;

-	spin_unlock_irqrestore(&(bdp->bd_lock), lock_flag);
+	spin_unlock(&(bdp->bd_lock));
 }

 /* ====================================================================== */
@@ -2471,7 +2423,7 @@
 	/* clear the dump counter complete word */
 	pcmd_complete = e100_cmd_complete_location(bdp);
 	*pcmd_complete = 0;
-	wmb();
+	mb();

 	if (!e100_wait_exec_cmplx(bdp, bdp->stat_cnt_phys, SCB_CUC_DUMP_ADDR))
 		return false;
@@ -2603,7 +2555,7 @@
 	ntcb_hdr->cb_status = 0;
 	ntcb_hdr->cb_lnk_ptr = 0;

-	wmb();
+	mb();
 	if (in_interrupt())
 		return e100_delayed_exec_non_cu_cmd(bdp, command);

===== drivers/net/e100/e100_test.c 1.6 vs edited =====
--- 1.6/drivers/net/e100/e100_test.c	Wed Nov  6 03:31:34 2002
+++ edited/drivers/net/e100/e100_test.c	Sat Dec  7 21:58:28 2002
@@ -309,7 +309,7 @@
 	memset((void *) ((u8 *) tbd + sizeof (tbd_t)), 0xFF, 512);
 	/* The value of second 512 bytes is BA */
 	memset((void *) ((u8 *) tbd + sizeof (tbd_t) + 512), 0xBA, 512);
-	wmb();
+	mb();
 	rfd = pci_alloc_consistent(bdp->pdev, sizeof (rfd_t), &dma_handle);

 	if (rfd == NULL) {
@@ -328,7 +328,7 @@
 	bdp->loopback.dma_handle = dma_handle;
 	bdp->loopback.tcb = tcb;
 	bdp->loopback.rfd = rfd;
-	wmb();
+	mb();
 	return true;
 }

-------------- next part --------------
===== arch/ppc64/kernel/pSeries_lpar.c 1.17 vs edited =====
--- 1.17/arch/ppc64/kernel/pSeries_lpar.c	Tue Nov  5 19:23:49 2002
+++ edited/arch/ppc64/kernel/pSeries_lpar.c	Mon Dec  9 15:44:46 2002
@@ -461,7 +461,7 @@
 		return -1;

 	if (lpar_rc != H_Success)
-		panic("Bad return code from pte enter rc = %lx\n", lpar_rc);
+		//panic("Bad return code from pte enter rc = %lx\n", lpar_rc);

 	return slot;
 }
===== drivers/pci/probe.c 1.21 vs edited =====
--- 1.21/drivers/pci/probe.c	Sat Dec  7 05:31:55 2002
+++ edited/drivers/pci/probe.c	Sun Dec  8 12:13:16 2002
@@ -464,8 +464,10 @@
 	u8 hdr_type;

 	for (func = 0; func < 8; func++, temp->devfn++) {
+#if 0
 		if (func && !is_multi)		/* not a multi-function device */
 			continue;
+#endif
 		if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type))
 			continue;
 		temp->hdr_type = hdr_type & 0x7f;
@@ -473,10 +475,15 @@
 		dev = pci_scan_device(temp);
 		if (!dev)
 			continue;
+#if 0
 		if (!func) {
 			is_multi = hdr_type & 0x80;
 			first_dev = dev;
 		}
+#else
+		if (!first_dev)
+			first_dev = dev;
+#endif

 		/*
 		 * Link the device to both the global PCI device chain and

-------------- next part --------------
===== drivers/pci/probe.c 1.15 vs edited =====
--- 1.15/drivers/pci/probe.c	Sat Oct  5 11:06:13 2002
+++ edited/drivers/pci/probe.c	Sat Oct  5 11:47:03 2002
@@ -152,7 +152,7 @@
 		limit |= (io_limit_hi << 16);
 	}

-	if (base && base <= limit) {
+	if (base <= limit) {
 		res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
 		res->start = base;
 		res->end = limit + 0xfff;
-------------- next part --------------
===== arch/ppc64/kernel/process.c 1.20 vs edited =====
--- 1.20/arch/ppc64/kernel/process.c	Mon Oct  7 19:14:30 2002
+++ edited/arch/ppc64/kernel/process.c	Tue Oct  8 19:04:43 2002
@@ -216,22 +216,30 @@
 /*
  * Set up a thread for executing a new program
  */
-void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
+void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp)
 {
-	/* NIP is *really* a pointer to the function descriptor for
+	unsigned long entry, toc, load_addr = regs->gpr[2];
+
+	/* fdptr is a relocated pointer to the function descriptor for
          * the elf _start routine.  The first entry in the function
          * descriptor is the entry address of _start and the second
          * entry is the TOC value we need to use.
          */
-	unsigned long *entry = (unsigned long *)nip;
-	unsigned long *toc   = entry + 1;
-
 	set_fs(USER_DS);
-	memset(regs->gpr, 0, sizeof(regs->gpr));
-	memset(&regs->ctr, 0, 4 * sizeof(regs->ctr));
-	__get_user(regs->nip, entry);
+	__get_user(entry, (unsigned long *)fdptr);
+	__get_user(toc, (unsigned long *)fdptr+1);
+
+	/* Check whether the e_entry function descriptor entries
+	 * need to be relocated before we can use them.
+	 */
+	if ( load_addr != 0 ) {
+		entry += load_addr;
+		toc   += load_addr;
+	}
+
+	regs->nip = entry;
 	regs->gpr[1] = sp;
-	__get_user(regs->gpr[2], toc);
+	regs->gpr[2] = toc;
 	regs->msr = MSR_USER64;
 	if (last_task_used_math == current)
 		last_task_used_math = 0;
===== fs/binfmt_elf.c 1.29 vs edited =====
--- 1.29/fs/binfmt_elf.c	Fri Sep 20 11:14:32 2002
+++ edited/fs/binfmt_elf.c	Tue Oct  8 19:04:43 2002
@@ -456,6 +456,7 @@
 	unsigned int size;
 	unsigned long elf_entry, interp_load_addr = 0;
 	unsigned long start_code, end_code, start_data, end_data;
+	unsigned long reloc_func_desc = 0;
 	struct elfhdr elf_ex;
 	struct elfhdr interp_elf_ex;
   	struct exec interp_ex;
@@ -682,6 +683,7 @@
 				load_bias += error -
 				             ELF_PAGESTART(load_bias + vaddr);
 				load_addr += load_bias;
+				reloc_func_desc = load_addr;
 			}
 		}
 		k = elf_ppnt->p_vaddr;
@@ -728,6 +730,7 @@
 			send_sig(SIGSEGV, current, 0);
 			return 0;
 		}
+		reloc_func_desc = interp_load_addr;
 	} else {
 		elf_entry = elf_ex.e_entry;
 	}
@@ -785,10 +788,14 @@
 	/*
 	 * The ABI may specify that certain registers be set up in special
 	 * ways (on i386 %edx is the address of a DT_FINI function, for
-	 * example.  This macro performs whatever initialization to
-	 * the regs structure is required.
+	 * example.  In addition, it may also specify (eg, PowerPC64 ELF)
+	 * that the e_entry field is the address of the function descriptor
+	 * for the startup routine, rather than the address of the startup
+	 * routine itself.  This macro performs whatever initialization to
+	 * the regs structure is required as well as any relocations to the
+	 * function descriptor entries when executing dynamically links apps.
 	 */
-	ELF_PLAT_INIT(regs);
+	ELF_PLAT_INIT(regs, reloc_func_desc);
 #endif

 	start_thread(regs, elf_entry, bprm->p);
===== include/asm-ppc64/elf.h 1.3 vs edited =====
--- 1.3/include/asm-ppc64/elf.h	Sat Sep  7 17:13:43 2002
+++ edited/include/asm-ppc64/elf.h	Tue Oct  8 19:04:44 2002
@@ -84,6 +84,15 @@

 #define ELF_PLATFORM	(NULL)

+
+#define ELF_PLAT_INIT(_r, load_addr)	do { \
+	memset(_r->gpr, 0, sizeof(_r->gpr)); \
+	_r->ctr = _r->link = _r->xer = _r->ccr = 0; \
+	_r->gpr[2] = load_addr; \
+} while (0)
+
+
+
 #ifdef __KERNEL__
 #define SET_PERSONALITY(ex, ibcs2)				\
 do {	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\

-------------- next part --------------
===== include/linux/compiler.h 1.6 vs edited =====
--- 1.6/include/linux/compiler.h	Sun Sep  1 12:52:31 2002
+++ edited/include/linux/compiler.h	Thu Sep 19 17:40:30 2002
@@ -17,6 +17,6 @@
    shouldn't recognize the original var, and make assumptions about it */
 #define RELOC_HIDE(ptr, off)					\
   ({ unsigned long __ptr;					\
-    __asm__ ("" : "=g"(__ptr) : "0"(ptr));		\
+    __asm__ ("" : "=r"(__ptr) : "0"(ptr));		\
     (typeof(ptr)) (__ptr + (off)); })
 #endif /* __LINUX_COMPILER_H */
-------------- next part --------------
===== drivers/scsi/sym53c8xx_2/sym_glue.c 1.10 vs edited =====
--- 1.10/drivers/scsi/sym53c8xx_2/sym_glue.c	Fri Nov 22 16:34:45 2002
+++ edited/drivers/scsi/sym53c8xx_2/sym_glue.c	Mon Dec  9 13:31:31 2002
@@ -1112,6 +1112,7 @@
 	int sts = -1;
 	struct sym_eh_wait eh, *ep = &eh;
 	char devname[20];
+	unsigned long flags;

 	sprintf(devname, "%s:%d:%d", sym_name(np), cmd->target, cmd->lun);

@@ -1203,7 +1204,11 @@
 		ep->timer.data = (u_long)cmd;
 		ep->timed_out = 1;	/* Be pessimistic for once :) */
 		add_timer(&ep->timer);
+		local_save_flags(flags);
+		spin_unlock_irq(cmd->host->host_lock);
 		down(&ep->sem);
+		local_irq_restore(flags);
+		spin_lock(cmd->host->host_lock);
 		if (ep->timed_out)
 			sts = -2;
 	}



More information about the Linuxppc64-dev mailing list