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);