NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/54538 (wdc(4) regression after SATA NCQ merge)
The following reply was made to PR kern/54538; it has been noted by GNATS.
From: Izumi Tsutsui <tsutsui%ceres.dti.ne.jp@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc: jdolecek%netbsd.org@localhost, tsutsui%ceres.dti.ne.jp@localhost
Subject: Re: kern/54538 (wdc(4) regression after SATA NCQ merge)
Date: Tue, 10 Sep 2019 23:49:04 +0900
> It looks wdc_g1_do_reset() is not necessary for wdcprobe(),
This is not correct.
It's also necessary even in wdc_g1_probe(), otherwise the driver
silently hangs in wdcprobe().
> Anyway I'll try if your fix works or not.
The following dumb patch (that restores MD wdc do_reset() function
support for wdcprobe()) makes dreamcast G1IDE functional.
https://dmesgd.nycbug.org/index.cgi?do=view&id=5115
Index: dev/ic/wdc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wdc.c,v
retrieving revision 1.291
diff -u -p -d -r1.291 wdc.c
--- dev/ic/wdc.c 27 Oct 2018 05:38:08 -0000 1.291
+++ dev/ic/wdc.c 10 Sep 2019 14:31:22 -0000
@@ -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: dev/ic/wdcvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wdcvar.h,v
retrieving revision 1.98
diff -u -p -d -r1.98 wdcvar.h
--- dev/ic/wdcvar.h 7 Oct 2017 16:05:32 -0000 1.98
+++ dev/ic/wdcvar.h 10 Sep 2019 14:31:22 -0000
@@ -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);
Index: arch/dreamcast/dev/g1/wdc_g1.c
===================================================================
RCS file: /cvsroot/src/sys/arch/dreamcast/dev/g1/wdc_g1.c,v
retrieving revision 1.4
diff -u -p -d -r1.4 wdc_g1.c
--- arch/dreamcast/dev/g1/wdc_g1.c 9 Sep 2019 22:01:23 -0000 1.4
+++ arch/dreamcast/dev/g1/wdc_g1.c 10 Sep 2019 14:31:22 -0000
@@ -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
---
Note ATADEBUG part in wdc_g1.c is no longer necessary after the
following MI wdc.c fix:
http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/dev/ic/wdc.c#rev1.280
>> Fix a bug that wdcprobe1() accesses NULL pointer when the DEBUG_PROBE bit
>> is set in atadebug_mask variable. The caller passes data which has
>> temporary-generated wdc_softc in it, but the device_t has not initialized
>> because it's not determined yet. So it can't use device_xname(). Use
>> __function__ instead.
---
Izumi Tsutsui
Home |
Main Index |
Thread Index |
Old Index