From owner-freebsd-current Wed Sep 4 19:41:16 2002 Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0137737B400 for ; Wed, 4 Sep 2002 19:41:08 -0700 (PDT) Received: from tasogare.imasy.or.jp (tasogare.imasy.or.jp [202.227.24.5]) by mx1.FreeBSD.org (Postfix) with ESMTP id CB10143E42 for ; Wed, 4 Sep 2002 19:41:06 -0700 (PDT) (envelope-from iwasaki@jp.FreeBSD.org) Received: from localhost (iwa@tasogare.imasy.or.jp [202.227.24.5]) by tasogare.imasy.or.jp (8.11.6+3.4W/8.11.6/tasogare) with ESMTP/inet id g852emY81963; Thu, 5 Sep 2002 11:40:49 +0900 (JST) (envelope-from iwasaki@jp.FreeBSD.org) Date: Thu, 05 Sep 2002 11:40:39 +0900 (JST) Message-Id: <20020905.114039.10290552.iwasaki@jp.FreeBSD.org> To: sos@freebsd.dk Cc: current@FreeBSD.org Subject: [PATCH] 'ata_dmasetup: transfer active on this device!' problem on resume From: Mitsuru IWASAKI X-Mailer: Mew version 2.1 on Emacs 20.7 / Mule 4.0 (HANANOEN) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Hi, Soren. I got panics with 'ata_dmasetup: transfer active on this device!' on resume, and have made patches for this. Problem was that certain process is accessing ATA disk via DMA transfer on suspend, however the transfer was not completed in most cases, then ata_dmastart() (called by ata_reinit()) got panic on resume. My patches will do those things during suspend time; - wait for DMA transfer completion if it is on the way. - cancel new requests (yes, it's possible even during suspend time) for ATA disks and remain them in ATA queue. Could you review the patches and commit them if OK? Thanks Index: ata-all.c =================================================================== RCS file: /home/ncvs/src/sys/dev/ata/ata-all.c,v retrieving revision 1.153 diff -u -r1.153 ata-all.c --- ata-all.c 9 Aug 2002 20:51:53 -0000 1.153 +++ ata-all.c 4 Sep 2002 10:21:22 -0000 @@ -279,8 +279,46 @@ } int +ata_suspend(device_t dev) +{ + struct ata_channel *ch; + + ch = device_get_softc(dev); + +#ifdef DEV_ATADISK + if (ch->devices & ATA_ATA_MASTER && ch->device[MASTER].driver) { + ch->device[MASTER].suspended = 1; + if (ch->device[MASTER].mode >= ATA_DMA) { + ata_waitdmadone(&ch->device[MASTER]); + } + } + if (ch->devices & ATA_ATA_SLAVE && ch->device[SLAVE].driver) { + ch->device[SLAVE].suspended = 1; + if (ch->device[SLAVE].mode >= ATA_DMA) { + ata_waitdmadone(&ch->device[SLAVE]); + } + } +#endif + + return 0; +} + +int ata_resume(device_t dev) { + struct ata_channel *ch; + + ch = device_get_softc(dev); + +#ifdef DEV_ATADISK + if (ch->devices & ATA_ATA_MASTER && ch->device[MASTER].driver) { + ch->device[MASTER].suspended = 0; + } + if (ch->devices & ATA_ATA_SLAVE && ch->device[SLAVE].driver) { + ch->device[SLAVE].suspended = 0; + } +#endif + return ata_reinit(device_get_softc(dev)); } @@ -674,6 +712,20 @@ ad_start(&ch->device[MASTER]); if (ch->devices & (ATA_ATA_SLAVE) && ch->device[SLAVE].driver) ad_start(&ch->device[SLAVE]); + } + if (ch->devices & (ATA_ATA_MASTER) && ch->device[MASTER].driver) { + if (ch->device[MASTER].suspended && ch->device[MASTER].mode >= ATA_DMA) { + printf("%s: going to suspend, ignoring.\n", __func__); + splx(s); + return; + } + } + if (ch->devices & (ATA_ATA_SLAVE) && ch->device[SLAVE].driver) { + if (ch->device[SLAVE].suspended && ch->device[MASTER].mode >= ATA_DMA) { + printf("%s: going to suspend, ignoring.\n", __func__); + splx(s); + return; + } } if ((ad_request = TAILQ_FIRST(&ch->ata_queue))) { TAILQ_REMOVE(&ch->ata_queue, ad_request, chain); Index: ata-all.h =================================================================== RCS file: /home/ncvs/src/sys/dev/ata/ata-all.h,v retrieving revision 1.53 diff -u -r1.53 ata-all.h --- ata-all.h 18 Apr 2002 19:11:43 -0000 1.53 +++ ata-all.h 4 Sep 2002 06:25:24 -0000 @@ -189,6 +189,7 @@ int cmd; /* last cmd executed */ void *result; /* misc data */ struct ata_dmastate dmastate; /* dma state */ + int suspended; /* 0 = normal 1 = suspended */ }; /* structure describing an ATA channel */ @@ -252,6 +253,7 @@ int ata_probe(device_t); int ata_attach(device_t); int ata_detach(device_t); +int ata_suspend(device_t); int ata_resume(device_t); void ata_start(struct ata_channel *); @@ -280,6 +282,7 @@ int ata_dmasetup(struct ata_device *, caddr_t, int32_t); int ata_dmastart(struct ata_device *, caddr_t, int32_t, int); int ata_dmastatus(struct ata_channel *); +void ata_waitdmadone(struct ata_device *); int ata_dmadone(struct ata_device *); /* macros for locking a channel */ Index: ata-dma.c =================================================================== RCS file: /home/ncvs/src/sys/dev/ata/ata-dma.c,v retrieving revision 1.100 diff -u -r1.100 ata-dma.c --- ata-dma.c 19 Jul 2002 22:14:54 -0000 1.100 +++ ata-dma.c 4 Sep 2002 11:15:50 -0000 @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1284,8 +1285,11 @@ struct ata_dmastate *ds = &atadev->dmastate; struct ata_dmasetup_data_cb_args cba; - if (ds->flags & ATA_DS_ACTIVE) - panic("ata_dmasetup: transfer active on this device!"); + if (ds->flags & ATA_DS_ACTIVE) { + printf("ata_dmastart: transfer active on this device!\n"); + Debugger("ata_dmastart"); + return -1; + } cba.dmatab = ds->dmatab; bus_dmamap_sync(ds->cdmatag, ds->cdmamap, BUS_DMASYNC_PREWRITE); @@ -1312,6 +1316,16 @@ return 0; } +void +ata_waitdmadone(struct ata_device *atadev) +{ + if (atadev->dmastate.flags & ATA_DS_ACTIVE) { + printf("%s: waiting for ata_dmadone()\n", __func__); + tsleep(ata_dmadone, PRIBIO, "atawdma", 10 * hz); + printf("%s: done\n", __func__); + } +} + int ata_dmadone(struct ata_device *atadev) { @@ -1332,6 +1346,7 @@ error | ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR); ch->flags &= ~ATA_DMA_ACTIVE; ds->flags = 0; + wakeup((caddr_t)ata_dmadone); return (error & ATA_BMSTAT_MASK); } Index: ata-pci.c =================================================================== RCS file: /home/ncvs/src/sys/dev/ata/ata-pci.c,v retrieving revision 1.43 diff -u -r1.43 ata-pci.c --- ata-pci.c 19 Jul 2002 22:14:54 -0000 1.43 +++ ata-pci.c 4 Sep 2002 04:01:35 -0000 @@ -856,6 +856,7 @@ DEVMETHOD(device_probe, ata_pcisub_probe), DEVMETHOD(device_attach, ata_attach), DEVMETHOD(device_detach, ata_detach), + DEVMETHOD(device_suspend, ata_suspend), DEVMETHOD(device_resume, ata_resume), { 0, 0 } }; To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message