NetBSD-Bugs archive

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

Re: port-i386/47606: sleep in interrupt mode after error with USB disk (ahci)



The following reply was made to PR port-i386/47606; it has been noted by GNATS.

From: Alan Barrett <apb%cequrux.com@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc: 
Subject: Re: port-i386/47606: sleep in interrupt mode after error with USB
 disk (ahci)
Date: Sat, 2 Mar 2013 15:27:19 +0200

 On Sat, 02 Mar 2013, apb%cequrux.com@localhost wrote:
 >>Number:         47606
 >>Category:       port-i386
 >>Synopsis:       panic with ffs+wapbl on cgd on USB disk (ahci)
 
 I have edited the synopsis, to read:
 Synopsis:      sleep in interrupt mode after error with USB disk (ahci)
 
 The following patch makes wddone() print the error message before,
 instead of after, resetting the disk.  It won't prevent the panic, but
 at least there will be a message about a disk error just before the
 panic.
 
 Index: sys/dev/ata/wd.c
 ===================================================================
 --- sys/dev/ata/wd.c   9 Jan 2013 22:03:49 -0000       1.402
 +++ sys/dev/ata/wd.c   2 Mar 2013 10:31:33 -0000
 @@ -748,6 +748,7 @@ wddone(void *v)
        struct wd_softc *wd = device_private(v);
        struct buf *bp = wd->sc_bp;
        const char *errmsg;
 +      int do_reset_drive = 0;
        int do_perror = 0;
   
        ATADEBUG_PRINT(("wddone %s\n", device_xname(wd->sc_dev)),
 @@ -758,26 +759,29 @@ wddone(void *v)
        switch (wd->sc_wdc_bio.error) {
        case ERR_DMA:
                errmsg = "DMA error";
 +              do_reset_drive = 1;
                goto retry;
        case ERR_DF:
                errmsg = "device fault";
 +              do_reset_drive = 1;
                goto retry;
        case TIMEOUT:
                errmsg = "device timeout";
 +              do_reset_drive = 1;
                goto retry;
        case ERR_RESET:
                errmsg = "channel reset";
 -              goto retry2;
 +              do_reset_drive = 0;
 +              goto retry;
        case ERROR:
                /* Don't care about media change bits */
                if (wd->sc_wdc_bio.r_error != 0 &&
                    (wd->sc_wdc_bio.r_error & ~(WDCE_MC | WDCE_MCR)) == 0)
                        goto noerror;
                errmsg = "error";
 +              do_reset_drive = 1;
                do_perror = 1;
 -retry:                /* Just reset and retry. Can we do more ? */
 -              (*wd->atabus->ata_reset_drive)(wd->drvp, AT_RST_NOCMD, NULL);
 -retry2:
 +retry:                /* print message, reset, and retry. Can we do more ? */
                diskerr(bp, "wd", errmsg, LOG_PRINTF,
                    wd->sc_wdc_bio.blkdone, wd->sc_dk.dk_label);
                if (wd->retries < WDIORETRIES)
 @@ -785,6 +789,9 @@ retry2:
                printf("\n");
                if (do_perror)
                        wdperror(wd);
 +              if (do_reset_drive)
 +                      (*wd->atabus->ata_reset_drive)(wd->drvp, AT_RST_NOCMD,
 +                          NULL);
                if (wd->retries < WDIORETRIES) {
                        wd->retries++;
                        callout_reset(&wd->sc_restart_ch, RECOVERYTIME,
 


Home | Main Index | Thread Index | Old Index