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

Re: ESP DMA and sbus (was: HyperSPARC patches (?))



On Thu, Apr 27, 2006 at 06:39:57PM +0100, Martin Habets wrote:
> I plan to try the eh locking patch posted next, and maybe something like
> 2.6.8 after that if it is still not working. Unless someone has a better
> proposal.

An update on this: the eh locking patch did not help. 2.6.8 caused an
oops on boot. I tried 2.6.17-rc3, but loading any module fails with:
  module crc32: Unknown relocation: 17
so that is not usable. I sure hope someone will fix this before 2.6.17
proper...

Some other pieces of random info:

- After reading another thread here I switched from gcc 3.3.5 to gcc 3.4.4.

- The problem only affects one controller at a time, so for people seeing
this on hard disks I would recommend moving one to another controller
(and report if that helped).

- Another important piece of information to gather is the DMA
version. This is displayed when the kernel boot, in my case:
 dma2: ESC Revision 1

I have attached my changes to esp.c, which dump more data.
The changes to ESPDATA and ESPSTAT show how you can restrict the debug
output to just one controller.

My latest error output with those changes:
palantir9:~# tar tvf /dev/nst0
drwxr-xr-x root/root         0 2006-04-27 03:48:05 boot/
... more good output ...
-rw-r--r-- root/root   2320481 2004-05-20 17:53:25 boot/vmlinux-2.4.26-sparc32
esp1: DMA error 4004430e
esp1: dumping state
esp1: dma -- cond_reg<4004430e> addr<f0400000> count<00001fde>
dma: running<0> allocated<1> addr<0> nbytes<00000000> real<00000000>
esp1: SW [sreg<01> sstep<04> ireg<10>]
STEP<CMD_SENT_OK> INTREG< BSERV >
esp1: HW reread [sreg<01> sstep<c4> ireg<00>]
STEP<CMD_SENT_OK> INTREG< >
esp1: current command [tgt<00> lun<00> pphase<CLUELESS> cphase<DATAIN>]
esp1: disconnected 
esp1: Resetting scsi bus
esp1: SCSI bus reset interrupt
st0: Error 80000 (sugg. bt 0x0, driver bt 0x0, host bt 0x8).
tar: /dev/nst0: Cannot read: Input/output error
esp1: Warning, live target 0 not responding to selection.
st0: Error 60000 (sugg. bt 0x0, driver bt 0x0, host bt 0x6).
tar: /dev/nst0: Cannot read: Input/output error

The dma address inside sbus_dma being zero looks not right to me.

Any hints/tips welcome...
-- 
Martin
--- esp.c.orig	2006-04-28 13:49:41.000000000 +0100
+++ esp.c	2006-05-04 17:00:33.000000000 +0100
@@ -56,11 +56,11 @@
 /*#define DEBUG_ESP_DATA*/
 /* #define DEBUG_ESP_QUEUE */
 /*#define DEBUG_ESP_DISCONNECT*/
-/*#define DEBUG_ESP_STATUS*/
+/* #define DEBUG_ESP_STATUS */
 /* #define DEBUG_ESP_PHASES */
 /* #define DEBUG_ESP_WORKBUS */
 /* #define DEBUG_STATE_MACHINE */
-/* #define DEBUG_ESP_CMDS */
+/*#define DEBUG_ESP_CMDS*/
 /* #define DEBUG_ESP_IRQS */
 /* #define DEBUG_SDTR */
 /* #define DEBUG_ESP_SG */
@@ -84,7 +84,7 @@
 #endif
 
 #if defined(DEBUG_ESP_DATA)
-#define ESPDATA(foo)  printk foo
+#define ESPDATA(foo)  if (esp->esp_id == 1) printk foo
 #else
 #define ESPDATA(foo)
 #endif
@@ -102,7 +102,7 @@
 #endif
 
 #if defined(DEBUG_ESP_STATUS)
-#define ESPSTAT(foo)  printk foo
+#define ESPSTAT(foo)  if (esp->esp_id == 1) printk foo
 #else
 #define ESPSTAT(foo)
 #endif
@@ -386,8 +386,10 @@
 #ifdef DEBUG_ESP_CMDS
 static inline void esp_cmd(struct esp *esp, u8 cmd)
 {
+	if (esp->esp_id == 1) {
 	esp->espcmdlog[esp->espcmdent] = cmd;
 	esp->espcmdent = (esp->espcmdent + 1) & 31;
+	}
 	sbus_writeb(cmd, esp->eregs + ESP_CMD);
 }
 #else
@@ -490,6 +492,7 @@
 	if (esp->dma->revision != dvmahme) {
 		tmp = sbus_readl(esp->dregs + DMA_CSR);
 		sbus_writel(tmp | DMA_RST_SCSI, esp->dregs + DMA_CSR);
+		__delay(400);			/* let the bits set ;) */
 		sbus_writel(tmp & ~DMA_RST_SCSI, esp->dregs + DMA_CSR);
 	}
 	switch (esp->dma->revision) {
@@ -1888,22 +1891,42 @@
 static void esp_dump_state(struct esp *esp)
 {
 	struct scsi_cmnd *SCptr = esp->current_SC;
+	struct sbus_dma *dma_ptr = esp->dma;
+	int	sstep, ireg;
+	__u32	addr;
 #ifdef DEBUG_ESP_CMDS
 	int i;
 #endif
 
 	ESPLOG(("esp%d: dumping state\n", esp->esp_id));
-	ESPLOG(("esp%d: dma -- cond_reg<%08x> addr<%08x>\n",
+	addr = sbus_readl(esp->dregs + DMA_ADDR);
+	ESPLOG(("esp%d: dma -- cond_reg<%08x> addr<%08x> count<%08x>\n",
 		esp->esp_id,
 		sbus_readl(esp->dregs + DMA_CSR),
-		sbus_readl(esp->dregs + DMA_ADDR)));
+		addr,
+		sbus_readl(esp->dregs + DMA_COUNT)));
+	ESPLOG(("dma: running<%d> allocated<%d> addr<%lx> nbytes<%08x> real<%08x>\n",
+		dma_ptr->running, dma_ptr->allocated, dma_ptr->addr, dma_ptr->nbytes, dma_ptr->realbytes));
 	ESPLOG(("esp%d: SW [sreg<%02x> sstep<%02x> ireg<%02x>]\n",
 		esp->esp_id, esp->sreg, esp->seqreg, esp->ireg));
+#ifdef DEBUG_ESP
+	esp_print_seqreg(esp->seqreg);
+	ESPLOG((" "));
+	esp_print_ireg(esp->ireg);
+	ESPLOG(("\n"));
+#endif
+	sstep = sbus_readb(esp->eregs + ESP_SSTEP);
+	ireg = sbus_readb(esp->eregs + ESP_INTRPT);
 	ESPLOG(("esp%d: HW reread [sreg<%02x> sstep<%02x> ireg<%02x>]\n",
 		esp->esp_id,
 		sbus_readb(esp->eregs + ESP_STATUS),
-		sbus_readb(esp->eregs + ESP_SSTEP),
-		sbus_readb(esp->eregs + ESP_INTRPT)));
+		sstep, ireg));
+#ifdef DEBUG_ESP
+	esp_print_seqreg(sstep);
+	ESPLOG((" "));
+	esp_print_ireg(ireg);
+	ESPLOG(("\n"));
+#endif
 #ifdef DEBUG_ESP_CMDS
 	printk("esp%d: last ESP cmds [", esp->esp_id);
 	i = (esp->espcmdent - 1) & 31;
@@ -4210,10 +4233,12 @@
 		 */
 		ESPLOG(("esp%d: DMA error %08x\n", esp->esp_id,
 			sbus_readl(esp->dregs + DMA_CSR)));
+		esp_dump_state(esp);
 
 		/* DMA gate array itself must be reset to clear the
 		 * error condition.
 		 */
+		ESP_INTSOFF(esp->dregs);
 		esp_reset_dma(esp);
 
 		what_next = do_reset_bus;
@@ -4394,6 +4419,7 @@
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 1,
 	.use_clustering		= ENABLE_CLUSTERING,
+/*	.unchecked_isa_dma	= 1, */
 };
 
 #include "scsi_module.c"

Reply to: