Module Name:    src
Committed By:   tsutsui
Date:           Sat Sep 14 17:11:39 UTC 2019

Modified Files:
        src/sys/arch/dreamcast/dev/g1: wdc_g1.c
        src/sys/dev/ic: wdc.c wdcvar.h

Log Message:
Restore interface to pass a MD reset function to MI wdcprobe().

Fixes silent hang on G1IDE on Dreamcast. PR kern/54538
Should be pulled up to netbsd-9 with the previous changes.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/dreamcast/dev/g1/wdc_g1.c
cvs rdiff -u -r1.291 -r1.292 src/sys/dev/ic/wdc.c
cvs rdiff -u -r1.98 -r1.99 src/sys/dev/ic/wdcvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/dreamcast/dev/g1/wdc_g1.c
diff -u src/sys/arch/dreamcast/dev/g1/wdc_g1.c:1.4 src/sys/arch/dreamcast/dev/g1/wdc_g1.c:1.5
--- src/sys/arch/dreamcast/dev/g1/wdc_g1.c:1.4	Mon Sep  9 22:01:23 2019
+++ src/sys/arch/dreamcast/dev/g1/wdc_g1.c	Sat Sep 14 17:11:39 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: wdc_g1.c,v 1.4 2019/09/09 22:01:23 jdolecek Exp $ */
+/* $NetBSD: wdc_g1.c,v 1.5 2019/09/14 17:11:39 tsutsui Exp $ */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -62,9 +62,7 @@ struct wdc_g1_softc {
 
 static int	wdc_g1_probe(device_t, cfdata_t, void *);
 static void	wdc_g1_attach(device_t, device_t, void *);
-#if 0
 static void	wdc_g1_do_reset(struct ata_channel *, int);
-#endif
 static int	wdc_g1_intr(void *);
 
 CFATTACH_DECL_NEW(wdc_g1bus, sizeof(struct wdc_g1_softc),
@@ -76,18 +74,11 @@ wdc_g1_probe(device_t parent, cfdata_t c
 	struct g1bus_attach_args *ga = aux;
 	struct wdc_regs wdr;
 	int result = 0, i;
-#ifdef ATADEBUG
-	struct device dev;
-#endif
 
 	*((volatile uint32_t *)0xa05f74e4) = 0x1fffff;
 	for (i = 0; i < 0x200000 / 4; i++)
 		(void)((volatile uint32_t *)0xa0000000)[i];
 
-#if 0
-	wdc.reset = wdc_g1_do_reset;
-#endif
-
 	wdr.cmd_iot = ga->ga_memt;
 	if (bus_space_map(wdr.cmd_iot, WDC_G1_CMD_ADDR,
 	    WDC_G1_REG_NPORTS * 4, 0, &wdr.cmd_baseioh))
@@ -106,12 +97,7 @@ wdc_g1_probe(device_t parent, cfdata_t c
 	    WDC_G1_AUXREG_NPORTS, 0, &wdr.ctl_ioh))
 	  goto outunmap;
 
-#ifdef ATADEBUG
-	/* fake up device name for ATADEBUG_PRINT() with DEBUG_PROBE */
-	memset(&dev, 0, sizeof(dev));
-	strncat(dev.dv_xname, "wdc(g1probe)", sizeof(dev.dv_xname));
-#endif
-	result = wdcprobe(&wdr);
+	result = wdcprobe_with_reset(&wdr, wdc_g1_do_reset);
 	
 	bus_space_unmap(wdr.ctl_iot, wdr.ctl_ioh, WDC_G1_AUXREG_NPORTS);
  outunmap:
@@ -157,9 +143,7 @@ wdc_g1_attach(struct device *parent, str
 	sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanlist;
 	sc->sc_wdcdev.sc_atac.atac_nchannels = 1;
 	sc->sc_wdcdev.wdc_maxdrives = 2;
-#if 0
 	sc->sc_wdcdev.reset = wdc_g1_do_reset;
-#endif
 	sc->ata_channel.ch_channel = 0;
 	sc->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
 
@@ -180,12 +164,11 @@ wdc_g1_intr(void *arg)
 	return wdcintr(arg);
 }
 
-#if 0
 /*
- * This does what the generic wdc_do_reset() does, only with unnecessary
- * additional GD-ROM reset. Keep code around in case this turns out to be
- * actually useful/necessary. ATAPI code should do it's own reset in either
- * case anyway.
+ * This does what the generic wdc_do_reset() does, with additional
+ * GD-ROM reset. GD-ROM is a very early ATAPI device appeared in 1998
+ * and it doesn't reset itself by the WDCTL_RST in AUX_CTLR but requires
+ * ATAPI_SOFT_RESET command to reset whole device as a master.
  */
 static void
 wdc_g1_do_reset(struct ata_channel *chp, int poll)
@@ -220,4 +203,3 @@ wdc_g1_do_reset(struct ata_channel *chp,
 	if (poll != 0)
 		splx(s);
 }
-#endif

Index: src/sys/dev/ic/wdc.c
diff -u src/sys/dev/ic/wdc.c:1.291 src/sys/dev/ic/wdc.c:1.292
--- src/sys/dev/ic/wdc.c:1.291	Sat Oct 27 05:38:08 2018
+++ src/sys/dev/ic/wdc.c	Sat Sep 14 17:11:39 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: wdc.c,v 1.291 2018/10/27 05:38:08 maya Exp $ */
+/*	$NetBSD: wdc.c,v 1.292 2019/09/14 17:11:39 tsutsui Exp $ */
 
 /*
  * Copyright (c) 1998, 2001, 2003 Manuel Bouyer.  All rights reserved.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.291 2018/10/27 05:38:08 maya Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.292 2019/09/14 17:11:39 tsutsui Exp $");
 
 #include "opt_ata.h"
 #include "opt_wdc.h"
@@ -477,6 +477,14 @@ wdc_drvprobe(struct ata_channel *chp)
 int
 wdcprobe(struct wdc_regs *wdr)
 {
+
+	return wdcprobe_with_reset(wdr, NULL);
+}
+
+int
+wdcprobe_with_reset(struct wdc_regs *wdr,
+    void (*do_reset)(struct ata_channel *, int))
+{
 	struct wdc_softc wdc;
 	struct ata_channel ch;
 	int rv;
@@ -487,9 +495,8 @@ wdcprobe(struct wdc_regs *wdr)
 	ch.ch_atac = &wdc.sc_atac;
 	wdc.regs = wdr;
 
-	/* default reset method */
-	if (wdc.reset == NULL)
-		wdc.reset = wdc_do_reset;
+	/* check the MD reset method */
+	wdc.reset = (do_reset != NULL) ? do_reset : wdc_do_reset;
 
 	rv = wdcprobe1(&ch, 1);
 

Index: src/sys/dev/ic/wdcvar.h
diff -u src/sys/dev/ic/wdcvar.h:1.98 src/sys/dev/ic/wdcvar.h:1.99
--- src/sys/dev/ic/wdcvar.h:1.98	Sat Oct  7 16:05:32 2017
+++ src/sys/dev/ic/wdcvar.h	Sat Sep 14 17:11:39 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: wdcvar.h,v 1.98 2017/10/07 16:05:32 jdolecek Exp $	*/
+/*	$NetBSD: wdcvar.h,v 1.99 2019/09/14 17:11:39 tsutsui Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc.
@@ -145,6 +145,8 @@ void	wdc_allocate_regs(struct wdc_softc 
 void	wdc_init_shadow_regs(struct wdc_regs *);
 
 int	wdcprobe(struct wdc_regs *);
+int	wdcprobe_with_reset(struct wdc_regs *,
+	    void (*)(struct ata_channel *, int));
 void	wdcattach(struct ata_channel *);
 int	wdcdetach(device_t, int);
 void	wdc_childdetached(device_t, device_t);

Reply via email to