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

Re: Hangs with 100baseTX, RedHat 7.1, kernel 2.4.x and AlphaPC 164



On Thu, Oct 04, 2001 at 05:12:49PM +0200, Mads Peter Bach wrote:
> 
> I've been trying to a net install of RedHat 7.1 on a machine with a
> Digital AlphaPC 164 (not SX/LX) motherboard, but failed miserably,
> due to machine hangs.

I'll bet you're running from SRM console, right?

> Last week, I finally installed from a CDROM instead, which went
> smoothly. It turns out, that the reason the net install didn't work,
> was that any heavy 100baseTX ethernet activity, using normal size
> packets hung the machine.  I've tried multiple ethernet interfaces,
> both RealTek RTL-8139 based, and DC21040 based, in 32 and 64 bit
> slots. When I finally dug up an old 10baseTX ISA card, the problems
> went away.

Yes, network traffic (even "ping" did it for me) seems to exacerbate
the problem.

> The strange thing is, that the cards work fine, if I use a 2.2 kernel
> (tested with 2.2.19). Others have posted that they needed to enable
> CONFIG_PCI_QUIRKS, but that doesn't seem to be necessary for me (I've
> haven't tested with heavy trafic more than 15 minutes, though).

Yes, well, the 2.2. kernels dealt with a PC164 "anomaly" much better,
and even 2.4.10 deals with it, but ONLY if you've booted from MILO.

Use the attached patch against 2.4.10, and you should have better
results. These patches, among others, are in the process of being
submitted to Linus for 2.4.11, hopefully.

--Jay++

-----------------------------------------------------------------------------
Jay A Estabrook                            Alpha Engineering - LINUX Project
Compaq Computer Corp. - MRO1-2/K20         (508) 467-2080
200 Forest Street, Marlboro MA 01752       Jay.Estabrook@compaq.com
-----------------------------------------------------------------------------
diff -ur LINUX/linux-2.4.10/arch/alpha/kernel/setup.c PATCH/linux-2.4.10/arch/alpha/kernel/setup.c
--- LINUX/linux-2.4.10/arch/alpha/kernel/setup.c	Thu Aug 16 23:48:33 2001
+++ PATCH/linux-2.4.10/arch/alpha/kernel/setup.c	Thu Sep 27 17:45:08 2001
@@ -85,7 +93,7 @@
 
 static struct alpha_machine_vector *get_sysvec(long, long, long);
 static struct alpha_machine_vector *get_sysvec_byname(const char *);
-static void get_sysnames(long, long, char **, char **);
+static void get_sysnames(long, long, long, char **, char **);
 
 static char command_line[COMMAND_LINE_SIZE];
 char saved_command_line[COMMAND_LINE_SIZE];
@@ -537,14 +545,14 @@
 	/*
 	 * Indentify and reconfigure for the current system.
 	 */
+	cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset);
+
 	get_sysnames(hwrpb->sys_type, hwrpb->sys_variation,
-		     &type_name, &var_name);
+		     cpu->type, &type_name, &var_name);
 	if (*var_name == '0')
 		var_name = "";
 
 	if (!vec) {
-		cpu = (struct percpu_struct*)
-			((char*)hwrpb + hwrpb->processor_offset);
 		vec = get_sysvec(hwrpb->sys_type, hwrpb->sys_variation,
 				 cpu->type);
 	}
@@ -801,6 +809,8 @@
 		/* Member ID is a bit-field. */
 		long member = (variation >> 10) & 0x3f;
 
+		cpu &= 0xffffffff; /* make it usable */
+
 		switch (type) {
 		case ST_DEC_ALCOR:
 			if (member < N(alcor_indices))
@@ -809,6 +819,10 @@
 		case ST_DEC_EB164:
 			if (member < N(eb164_indices))
 				vec = eb164_vecs[eb164_indices[member]];
+			/* PC164 may show as EB164 variation with EV56 CPU,
+			   but, since no true EB164 had anything but EV5... */
+			if (vec == &eb164_mv && cpu == EV56_CPU)
+				vec = &pc164_mv;
 			break;
 		case ST_DEC_EB64P:
 			if (member < N(eb64p_indices))
@@ -827,21 +841,18 @@
 				vec = tsunami_vecs[tsunami_indices[member]];
 			break;
 		case ST_DEC_1000:
-			cpu &= 0xffffffff;
 			if (cpu == EV5_CPU || cpu == EV56_CPU)
 				vec = &mikasa_primo_mv;
 			else
 				vec = &mikasa_mv;
 			break;
 		case ST_DEC_NORITAKE:
-			cpu &= 0xffffffff;
 			if (cpu == EV5_CPU || cpu == EV56_CPU)
 				vec = &noritake_primo_mv;
 			else
 				vec = &noritake_mv;
 			break;
 		case ST_DEC_2100_A500:
-			cpu &= 0xffffffff;
 			if (cpu == EV5_CPU || cpu == EV56_CPU)
 				vec = &sable_gamma_mv;
 			else
@@ -905,7 +916,7 @@
 }
 
 static void
-get_sysnames(long type, long variation,
+get_sysnames(long type, long variation, long cpu,
 	     char **type_name, char **variation_name)
 {
 	long member;
@@ -938,12 +949,18 @@
 
 	member = (variation >> 10) & 0x3f; /* member ID is a bit-field */
 
+	cpu &= 0xffffffff; /* make it usable */
+
 	switch (type) { /* select by family */
 	default: /* default to variation "0" for now */
 		break;
 	case ST_DEC_EB164:
 		if (member < N(eb164_indices))
 			*variation_name = eb164_names[eb164_indices[member]];
+		/* PC164 may show as EB164 variation, but with EV56 CPU,
+		   so, since no true EB164 had anything but EV5... */
+		if (eb164_indices[member] == 0 && cpu == EV56_CPU)
+			*variation_name = eb164_names[1]; /* make it PC164 */
 		break;
 	case ST_DEC_ALCOR:
 		if (member < N(alcor_indices))
@@ -1054,7 +1071,7 @@
 		cpu_name = cpu_names[cpu_index];
 
 	get_sysnames(hwrpb->sys_type, hwrpb->sys_variation,
-		     &systype_name, &sysvariation_name);
+		     cpu->type, &systype_name, &sysvariation_name);
 
 	nr_processors = get_nr_processors(cpu, hwrpb->nr_processors);
 
diff -ur LINUX/linux-2.4.10/arch/alpha/kernel/sys_cabriolet.c PATCH/linux-2.4.10/arch/alpha/kernel/sys_cabriolet.c
--- LINUX/linux-2.4.10/arch/alpha/kernel/sys_cabriolet.c	Sat Feb 24 22:54:55 2001
+++ PATCH/linux-2.4.10/arch/alpha/kernel/sys_cabriolet.c	Fri Sep 28 10:34:51 2001
@@ -106,12 +106,12 @@
 }
 
 static void __init
-cabriolet_init_irq(void)
+common_init_irq(void (*srm_dev_int)(unsigned long v, struct pt_regs *r))
 {
 	init_i8259a_irqs();
 
 	if (alpha_using_srm) {
-		alpha_mv.device_interrupt = srm_device_interrupt;
+		alpha_mv.device_interrupt = srm_dev_int;
 		init_srm_irqs(35, 0);
 	}
 	else {
@@ -131,8 +131,43 @@
 	setup_irq(16+4, &isa_cascade_irqaction);
 }
 
+static void __init
+cabriolet_init_irq(void)
+{
+	common_init_irq(srm_device_interrupt);
+}
+
 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_PC164)
 static void
+pc164_srm_device_interrupt(unsigned long v, struct pt_regs *r)
+{
+	/* In theory, the PC164 has the same interrupt hardware as
+	   the other Cabriolet based systems.  However, something 
+	   got screwed up late in the development cycle which broke
+	   the interrupt masking hardware.  Repeat, it is not 
+	   possible to mask and ack interrupts.  At all.
+
+	   In an attempt to work around this, while processing 
+	   interrupts, we do not allow the IPL to drop below what
+	   it is currently.  This prevents the possibility of
+	   recursion.  
+
+	   ??? Another option might be to force all PCI devices
+	   to use edge triggered rather than level triggered
+	   interrupts.  That might be too invasive though.  */
+
+	__min_ipl = getipl();
+	srm_device_interrupt(v, r);
+	__min_ipl = 0;
+}
+
+static void __init
+pc164_init_irq(void)
+{
+	common_init_irq(pc164_srm_device_interrupt);
+}
+
+static void
 pc164_device_interrupt(unsigned long v, struct pt_regs *r)
 {
 	/* In theory, the PC164 has the same interrupt hardware as
@@ -419,7 +454,7 @@
 	device_interrupt:	pc164_device_interrupt,
 
 	init_arch:		cia_init_arch,
-	init_irq:		cabriolet_init_irq,
+	init_irq:		pc164_init_irq,
 	init_rtc:		common_init_rtc,
 	init_pci:		alphapc164_init_pci,
 	pci_map_irq:		alphapc164_map_irq,

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