Subject: pciide problem fixed !
To: None <port-sparc64@netbsd.org, port-macppc@netbsd.org, current-users@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: current-users
Date: 01/12/2001 17:13:20
--NzB8fVQJ5HfG6fxh
Content-Type: text/plain; charset=us-ascii

Hi,
Paul Kranenburg pointed me a problem in the pciide code for controllers
in native mode (controllers on sparc64, macppc and maybe other machines,
add-on pciide cards, ...), which cause the bus reset to silently fail.
The main visible effect was that the drive was left with interrupt
disabled by openfirware, causing the 'lost interrupt' message when booting
from the disk. This is now fixed on sparc64, and should be on macppc
as well.
A second effect was that ATAPI devices were not detected on such controllers,
(the code uses ATAPI signature which is posted to registers after reset)
I have sucessfully used a ATAPI CD on a HPT366 with this change.
A less visible effect could be that the error recovery code (triggered by
lost interrupt, CrC error or DMA transfer error) could also fail on with
such controllers, causing the machine to lock up.

For the fix, you need pciide.c 1.105 and pciidevar.h 1.6 or (for the
impatient :) apply the patch below

--
Manuel Bouyer, LIP6, Universite Paris VI.           Manuel.Bouyer@lip6.fr
--

--NzB8fVQJ5HfG6fxh
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pciide.diff"

Index: pciide.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pci/pciide.c,v
retrieving revision 1.44.2.4
diff -u -r1.44.2.4 pciide.c
--- pciide.c	2001/01/05 17:36:16	1.44.2.4
+++ pciide.c	2001/01/11 22:43:10
@@ -671,10 +671,23 @@
 
 	if (pci_mapreg_map(pa, PCIIDE_REG_CTL_BASE(wdc_cp->channel),
 	    PCI_MAPREG_TYPE_IO, 0,
-	    &wdc_cp->ctl_iot, &wdc_cp->ctl_ioh, NULL, ctlsizep) != 0) {
+	    &wdc_cp->ctl_iot, &cp->ctl_baseioh, NULL, ctlsizep) != 0) {
 		printf("%s: couldn't map %s channel ctl regs\n",
 		    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
 		bus_space_unmap(wdc_cp->cmd_iot, wdc_cp->cmd_ioh, *cmdsizep);
+		return 0;
+	}
+	/*
+	 * In native mode, 4 bytes of I/O space are mapped for the control
+	 * register, the control register is at offset 2. Pass the generic
+	 * code a handle for only one byte at the rigth offset.
+	 */
+	if (bus_space_subregion(wdc_cp->ctl_iot, cp->ctl_baseioh, 2, 1,
+	    &wdc_cp->ctl_ioh) != 0) {
+		printf("%s: unable to subregion %s channel ctl regs\n",
+		    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
+		bus_space_unmap(wdc_cp->cmd_iot, wdc_cp->cmd_ioh, *cmdsizep);
+		bus_space_unmap(wdc_cp->cmd_iot, cp->ctl_baseioh, *ctlsizep);
 		return 0;
 	}
 	return (1);
Index: pciidevar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pci/pciidevar.h,v
retrieving revision 1.2.12.1
diff -u -r1.2.12.1 pciidevar.h
--- pciidevar.h	2000/11/20 11:42:35	1.2.12.1
+++ pciidevar.h	2001/01/11 22:43:10
@@ -1,4 +1,4 @@
-/*	$NetBSD: pciidevar.h,v 1.2.12.1 2000/11/20 11:42:35 bouyer Exp $	*/
+/*	$NetBSD$	*/
 
 /*
  * Copyright (c) 1998 Christopher G. Demetriou.  All rights reserved.
@@ -64,9 +64,10 @@
 	struct pciide_channel {			/* per-channel data */
 		struct channel_softc wdc_channel; /* generic part */
 		char		*name;
-		int		hw_ok;		/* hardware mapped & OK? */
-		int		compat;		/* is it compat? */
-		void		*ih;		/* compat or pci handle */
+		int		hw_ok;	/* hardware mapped & OK? */
+		int		compat;	/* is it compat? */
+		void		*ih;	/* compat or pci handle */
+		bus_space_handle_t ctl_baseioh; /* ctrl regs blk, native mode */
 		/* DMA tables and DMA map for xfer, for each drive */
 		struct pciide_dma_maps {
 			bus_dmamap_t    dmamap_table;

--NzB8fVQJ5HfG6fxh--